X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FAsmPrinter.cpp;h=246538b8c202dce001a263b9b378d08fd870483a;hb=6cde3e6e993126df756e3be5b9ef43540b904644;hp=3a79cf30772610a7646101a167e9c8cbcec6a65e;hpb=951755445821b92c3dc38f32b5c36e9875fa4318;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 3a79cf30772..246538b8c20 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -61,7 +61,7 @@ AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, : MachineFunctionPass(&ID), O(o), TM(tm), MAI(T), TRI(tm.getRegisterInfo()), OutContext(Ctx), OutStreamer(Streamer), - LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) { + LastMI(0), LastFn(0), Counter(~0U), SetCounter(0), PrevDLT(NULL) { DW = 0; MMI = 0; VerboseAsm = Streamer.isVerboseAsm(); } @@ -302,7 +302,7 @@ void AsmPrinter::EmitFunctionHeader() { OutStreamer.GetCommentOS() << '\n'; } - // Emit the CurrentFnSym. This is is a virtual function to allow targets to + // Emit the CurrentFnSym. This is a virtual function to allow targets to // do their wild and crazy things as required. EmitFunctionEntryLabel(); @@ -324,6 +324,64 @@ void AsmPrinter::EmitFunctionEntryLabel() { } +/// EmitComments - Pretty-print comments for instructions. +static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) { + const MachineFunction *MF = MI.getParent()->getParent(); + const TargetMachine &TM = MF->getTarget(); + + if (!MI.getDebugLoc().isUnknown()) { + DILocation DLT = MF->getDILocation(MI.getDebugLoc()); + + // Print source line info. + DIScope Scope = DLT.getScope(); + // Omit the directory, because it's likely to be long and uninteresting. + if (Scope.Verify()) + CommentOS << Scope.getFilename(); + else + CommentOS << ""; + CommentOS << ':' << DLT.getLineNumber(); + if (DLT.getColumnNumber() != 0) + CommentOS << ':' << DLT.getColumnNumber(); + CommentOS << '\n'; + } + + // Check for spills and reloads + int FI; + + const MachineFrameInfo *FrameInfo = MF->getFrameInfo(); + + // We assume a single instruction only has a spill or reload, not + // both. + const MachineMemOperand *MMO; + if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) { + if (FrameInfo->isSpillSlotObjectIndex(FI)) { + MMO = *MI.memoperands_begin(); + CommentOS << MMO->getSize() << "-byte Reload\n"; + } + } else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) { + if (FrameInfo->isSpillSlotObjectIndex(FI)) + CommentOS << MMO->getSize() << "-byte Folded Reload\n"; + } else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) { + if (FrameInfo->isSpillSlotObjectIndex(FI)) { + MMO = *MI.memoperands_begin(); + CommentOS << MMO->getSize() << "-byte Spill\n"; + } + } else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) { + if (FrameInfo->isSpillSlotObjectIndex(FI)) + CommentOS << MMO->getSize() << "-byte Folded Spill\n"; + } + + // Check for spill-induced copies + unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg, + SrcSubIdx, DstSubIdx)) { + if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) + CommentOS << " Reload Reuse\n"; + } +} + + + /// EmitFunctionBody - This method emits the body and trailer for a /// function. void AsmPrinter::EmitFunctionBody() { @@ -347,27 +405,28 @@ void AsmPrinter::EmitFunctionBody() { // FIXME: Clean up processDebugLoc. processDebugLoc(II, true); + if (VerboseAsm) + EmitComments(*II, OutStreamer.GetCommentOS()); + switch (II->getOpcode()) { - case TargetInstrInfo::DBG_LABEL: - case TargetInstrInfo::EH_LABEL: - case TargetInstrInfo::GC_LABEL: + case TargetOpcode::DBG_LABEL: + case TargetOpcode::EH_LABEL: + case TargetOpcode::GC_LABEL: printLabelInst(II); break; - case TargetInstrInfo::INLINEASM: + case TargetOpcode::INLINEASM: printInlineAsm(II); break; - case TargetInstrInfo::IMPLICIT_DEF: + case TargetOpcode::IMPLICIT_DEF: printImplicitDef(II); break; - case TargetInstrInfo::KILL: + case TargetOpcode::KILL: printKill(II); break; default: EmitInstruction(II); break; } - if (VerboseAsm) - EmitComments(*II); // FIXME: Clean up processDebugLoc. processDebugLoc(II, false); @@ -834,6 +893,31 @@ void AsmPrinter::EmitInt64(uint64_t Value) const { OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/); } +/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size +/// in bytes of the directive is specified by Size and Hi/Lo specify the +/// labels. This implicitly uses .set if it is available. +void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, + unsigned Size) const { + // Get the Hi-Lo expression. + const MCExpr *Diff = + MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), + MCSymbolRefExpr::Create(Lo, OutContext), + OutContext); + + if (!MAI->hasSetDirective()) { + OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/); + return; + } + + // Otherwise, emit with .set (aka assignment). + MCSymbol *SetLabel = + OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "set" + + Twine(SetCounter++)); + OutStreamer.EmitAssignment(SetLabel, Diff); + OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); +} + + //===----------------------------------------------------------------------===// // EmitAlignment - Emit an alignment directive to the specified power of @@ -858,11 +942,10 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, if (NumBits == 0) return; // No need to emit alignment. - unsigned FillValue = 0; if (getCurrentSection()->getKind().isText()) - FillValue = MAI->getTextAlignFillValue(); - - OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0); + OutStreamer.EmitCodeAlignment(1 << NumBits); + else + OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0); } /// LowerConstant - Lower the specified LLVM Constant to an MCExpr. @@ -963,8 +1046,14 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); } + // The MC library also has a right-shift operator, but it isn't consistently + // signed or unsigned between different targets. case Instruction::Add: case Instruction::Sub: + case Instruction::Mul: + case Instruction::SDiv: + case Instruction::SRem: + case Instruction::Shl: case Instruction::And: case Instruction::Or: case Instruction::Xor: { @@ -974,6 +1063,10 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { default: llvm_unreachable("Unknown binary operator constant cast expr"); case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); + case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx); + case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx); + case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx); + case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx); case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); @@ -1219,7 +1312,7 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI, if (DL.isUnknown()) return; DILocation CurDLT = MF->getDILocation(DL); - if (CurDLT.getScope().isNull()) + if (!CurDLT.getScope().Verify()) return; if (!BeforePrintingInsn) { @@ -1432,7 +1525,8 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { } } } - O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd() << '\n'; + O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd(); + OutStreamer.AddBlankLine(); } /// printImplicitDef - This method prints the specified machine instruction @@ -1441,7 +1535,8 @@ void AsmPrinter::printImplicitDef(const MachineInstr *MI) const { if (!VerboseAsm) return; O.PadToColumn(MAI->getCommentColumn()); O << MAI->getCommentString() << " implicit-def: " - << TRI->getName(MI->getOperand(0).getReg()) << '\n'; + << TRI->getName(MI->getOperand(0).getReg()); + OutStreamer.AddBlankLine(); } void AsmPrinter::printKill(const MachineInstr *MI) const { @@ -1453,14 +1548,14 @@ void AsmPrinter::printKill(const MachineInstr *MI) const { assert(op.isReg() && "KILL instruction must have only register operands"); O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "" : ""); } - O << '\n'; + OutStreamer.AddBlankLine(); } /// printLabel - This method prints a local label used by debug and /// exception handling tables. void AsmPrinter::printLabelInst(const MachineInstr *MI) const { printLabel(MI->getOperand(0).getImm()); - O << '\n'; + OutStreamer.AddBlankLine(); } void AsmPrinter::printLabel(unsigned Id) const { @@ -1646,7 +1741,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { } // Print the main label for the block. - if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) { + if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) { if (VerboseAsm) { // NOTE: Want this comment at start of line. O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':'; @@ -1693,6 +1788,39 @@ void AsmPrinter::printOffset(int64_t Offset) const { O << Offset; } +/// 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. + const 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; + + // Otherwise, check the last instruction. + const MachineInstr &LastInst = Pred->back(); + return !LastInst.getDesc().isBarrier(); +} + + + GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { if (!S->usesMetadata()) return 0; @@ -1717,75 +1845,3 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { return 0; } -/// EmitComments - Pretty-print comments for instructions -void AsmPrinter::EmitComments(const MachineInstr &MI) const { - if (!VerboseAsm) - return; - - if (!MI.getDebugLoc().isUnknown()) { - DILocation DLT = MF->getDILocation(MI.getDebugLoc()); - - // Print source line info. - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' '; - DIScope Scope = DLT.getScope(); - // Omit the directory, because it's likely to be long and uninteresting. - if (!Scope.isNull()) - O << Scope.getFilename(); - else - O << ""; - O << ':' << DLT.getLineNumber(); - if (DLT.getColumnNumber() != 0) - O << ':' << DLT.getColumnNumber(); - O << '\n'; - } - - // Check for spills and reloads - int FI; - - const MachineFrameInfo *FrameInfo = - MI.getParent()->getParent()->getFrameInfo(); - - // We assume a single instruction only has a spill or reload, not - // both. - const MachineMemOperand *MMO; - if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) { - if (FrameInfo->isSpillSlotObjectIndex(FI)) { - MMO = *MI.memoperands_begin(); - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Reload\n"; - } - } - else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) { - if (FrameInfo->isSpillSlotObjectIndex(FI)) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' ' - << MMO->getSize() << "-byte Folded Reload\n"; - } - } - else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) { - if (FrameInfo->isSpillSlotObjectIndex(FI)) { - MMO = *MI.memoperands_begin(); - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Spill\n"; - } - } - else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) { - if (FrameInfo->isSpillSlotObjectIndex(FI)) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' ' - << MMO->getSize() << "-byte Folded Spill\n"; - } - } - - // Check for spill-induced copies - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; - if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg, - SrcSubIdx, DstSubIdx)) { - if (MI.getAsmPrinterFlag(ReloadReuse)) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " Reload Reuse\n"; - } - } -} -