Skip to content
AsmPrinter.cpp 78.1 KiB
Newer Older
  MachineBasicBlock *Header = Loop->getHeader();
  assert(Header && "No header for loop");
  // If this block is not a loop header, just print out what is the loop header
  // and return.
  if (Header != &MBB) {
    AP.OutStreamer.AddComment("  in Loop: Header=BB" +
                              Twine(AP.getFunctionNumber())+"_" +
                              Twine(Loop->getHeader()->getNumber())+
                              " Depth="+Twine(Loop->getLoopDepth()));
    return;
  }
  // Otherwise, it is a loop header.  Print out information about child and
  // parent loops.
  raw_ostream &OS = AP.OutStreamer.GetCommentOS();

  PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());

  OS << "=>";
  OS.indent(Loop->getLoopDepth()*2-2);
  OS << "This ";
  if (Loop->empty())
    OS << "Inner ";
  OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
  PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
}


/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
Dan Gohman's avatar
Dan Gohman committed
  // Emit an alignment directive for this block, if needed.
  if (unsigned Align = MBB->getAlignment())
  // If the block has its address taken, emit any labels that were used to
  // reference the block.  It is possible that there is more than one label
  // here, because multiple LLVM BB's may have been RAUW'd to this block after
  // the references were generated.
  if (MBB->hasAddressTaken()) {
    const BasicBlock *BB = MBB->getBasicBlock();
      OutStreamer.AddComment("Block address taken");
    std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);

    for (unsigned i = 0, e = Syms.size(); i != e; ++i)
      OutStreamer.EmitLabel(Syms[i]);
  // Print some verbose block comments.
  if (isVerbose()) {
    if (const BasicBlock *BB = MBB->getBasicBlock())
      if (BB->hasName())
        OutStreamer.AddComment("%" + BB->getName());
    emitBasicBlockLoopComments(*MBB, LI, *this);
Dan Gohman's avatar
Dan Gohman committed
  // Print the main label for the block.
  if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) {
    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
      // NOTE: Want this comment at start of line, don't emit with AddComment.
      OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" +
                              Twine(MBB->getNumber()) + ":");
    OutStreamer.EmitLabel(MBB->getSymbol());
void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
                                bool IsDefinition) const {
  MCSymbolAttr Attr = MCSA_Invalid;
  switch (Visibility) {
  default: break;
  case GlobalValue::HiddenVisibility:
    if (IsDefinition)
      Attr = MAI->getHiddenVisibilityAttr();
    else
      Attr = MAI->getHiddenDeclarationVisibilityAttr();
    break;
  case GlobalValue::ProtectedVisibility:
    Attr = MAI->getProtectedVisibilityAttr();
    break;

  if (Attr != MCSA_Invalid)
    OutStreamer.EmitSymbolAttribute(Sym, Attr);
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
bool AsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
  // If this is a landing pad, it isn't a fall through.  If it has no preds,
  // then nothing falls through to it.
  if (MBB->isLandingPad() || MBB->pred_empty())
    return false;
  // If there isn't exactly one predecessor, it can't be a fall through.
  MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
  ++PI2;
  if (PI2 != MBB->pred_end())
    return false;
  // The predecessor has to be immediately before this block.
  MachineBasicBlock *Pred = *PI;
  if (!Pred->isLayoutSuccessor(MBB))
    return false;
  // If the block is completely empty, then it definitely does fall through.
  if (Pred->empty())
    return true;
  // Check the terminators in the previous blocks
  for (MachineBasicBlock::iterator II = Pred->getFirstTerminator(),
         IE = Pred->end(); II != IE; ++II) {
    MachineInstr &MI = *II;

    // If it is not a simple branch, we are in a table somewhere.
    if (!MI.isBranch() || MI.isIndirectBranch())
      return false;

    // If we are the operands of one of the branches, this is not
    // a fall through.
    for (MachineInstr::mop_iterator OI = MI.operands_begin(),
           OE = MI.operands_end(); OI != OE; ++OI) {
      const MachineOperand& OP = *OI;
      if (OP.isJTI())
        return false;
      if (OP.isMBB() && OP.getMBB() == MBB)
        return false;
    }
  }

  return true;
GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
  if (!S->usesMetadata())

  gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
  gcp_map_type::iterator GCPI = GCMap.find(S);
  if (GCPI != GCMap.end())
  const char *Name = S->getName().c_str();
  for (GCMetadataPrinterRegistry::iterator
         I = GCMetadataPrinterRegistry::begin(),
         E = GCMetadataPrinterRegistry::end(); I != E; ++I)
    if (strcmp(Name, I->getName()) == 0) {
      GCMetadataPrinter *GMP = I->instantiate();
      GMP->S = S;
      GCMap.insert(std::make_pair(S, GMP));
  report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));