#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
STATISTIC(EmittedInsts, "Number of machine instrs printed");
-static cl::opt<cl::boolOrDefault>
-AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
- cl::init(cl::BOU_UNSET));
-
-static bool getVerboseAsm(bool VDef) {
- switch (AsmVerbose) {
- default:
- case cl::BOU_UNSET: return VDef;
- case cl::BOU_TRUE: return true;
- case cl::BOU_FALSE: return false;
- }
-}
-
char AsmPrinter::ID = 0;
AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- const MCAsmInfo *T, bool VDef)
+ MCContext &Ctx, MCStreamer &Streamer,
+ const MCAsmInfo *T)
: MachineFunctionPass(&ID), O(o),
TM(tm), MAI(T), TRI(tm.getRegisterInfo()),
-
- OutContext(*new MCContext()),
- // FIXME: Pass instprinter to streamer.
- OutStreamer(*createAsmStreamer(OutContext, O, *T,
- TM.getTargetData()->isLittleEndian(),
- getVerboseAsm(VDef), 0)),
-
+ OutContext(Ctx), OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) {
DW = 0; MMI = 0;
- VerboseAsm = getVerboseAsm(VDef);
+ VerboseAsm = Streamer.isVerboseAsm();
}
AsmPrinter::~AsmPrinter() {
/// EmitFunctionBody - This method emits the body and trailer for a
/// function.
void AsmPrinter::EmitFunctionBody() {
+ // Emit target-specific gunk before the function body.
+ EmitFunctionBodyStart();
// Print out code for the function.
bool HasAnyRealCode = false;
// FIXME: Clean up processDebugLoc.
processDebugLoc(II, true);
- EmitInstruction(II);
-
+ switch (II->getOpcode()) {
+ case TargetInstrInfo::DBG_LABEL:
+ case TargetInstrInfo::EH_LABEL:
+ case TargetInstrInfo::GC_LABEL:
+ printLabelInst(II);
+ break;
+ case TargetInstrInfo::INLINEASM:
+ printInlineAsm(II);
+ break;
+ case TargetInstrInfo::IMPLICIT_DEF:
+ printImplicitDef(II);
+ break;
+ case TargetInstrInfo::KILL:
+ printKill(II);
+ break;
+ default:
+ EmitInstruction(II);
+ break;
+ }
if (VerboseAsm)
EmitComments(*II);
- O << '\n';
// FIXME: Clean up processDebugLoc.
processDebugLoc(II, false);
}
// If the function is empty and the object file uses .subsections_via_symbols,
- // then we need to emit *some* thing to the function body to prevent the
- // labels from collapsing together.
- if (MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) {
- // FIXME: EmitByte(0).
- O << "\tnop\n";
- }
+ // then we need to emit *something* to the function body to prevent the
+ // labels from collapsing together. Just emit a 0 byte.
+ if (MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)
+ OutStreamer.EmitIntValue(0, 1, 0/*addrspace*/);
+
+ // Emit target-specific gunk after the function body.
+ EmitFunctionBodyEnd();
if (MAI->hasDotTypeDotSizeDirective())
O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// Print out jump tables referenced by the function.
EmitJumpTableInfo();
+
+ OutStreamer.AddBlankLine();
}
}
switch (CE->getOpcode()) {
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- default: llvm_unreachable("FIXME: Don't support this constant cast expr");
+ default:
+ // If the code isn't optimized, there may be outstanding folding
+ // opportunities. Attempt to fold the expression using TargetData as a
+ // last resort before giving up.
+ if (Constant *C = ConstantFoldConstantExpression(CE, AP.TM.getTargetData()))
+ return LowerConstant(C, AP);
+#ifndef NDEBUG
+ CE->dump();
+#endif
+ llvm_unreachable("FIXME: Don't support this constant expr");
case Instruction::GetElementPtr: {
const TargetData &TD = *AP.TM.getTargetData();
// Generate a symbolic expression for the byte address
void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) {
uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ if (Size == 0) Size = 1; // An empty "_foo:" followed by a section is undef.
return OutStreamer.EmitZeros(Size, AddrSpace);
}
}
}
}
- O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd();
+ O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd() << '\n';
}
/// printImplicitDef - This method prints the specified machine instruction
if (!VerboseAsm) return;
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " implicit-def: "
- << TRI->getName(MI->getOperand(0).getReg());
+ << TRI->getName(MI->getOperand(0).getReg()) << '\n';
}
void AsmPrinter::printKill(const MachineInstr *MI) const {
assert(op.isReg() && "KILL instruction must have only register operands");
O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "<def>" : "<kill>");
}
+ O << '\n';
}
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
-void AsmPrinter::printLabel(const MachineInstr *MI) const {
+void AsmPrinter::printLabelInst(const MachineInstr *MI) const {
printLabel(MI->getOperand(0).getImm());
+ O << '\n';
}
void AsmPrinter::printLabel(unsigned Id) const {
}
}
-/// EmitComments - Pretty-print comments for basic blocks.
+/// PrintBasicBlockLoopComments - Pretty-print comments for basic blocks.
static void PrintBasicBlockLoopComments(const MachineBasicBlock &MBB,
const MachineLoopInfo *LI,
const AsmPrinter &AP) {
if (!VerboseAsm)
return;
- bool Newline = false;
-
if (!MI.getDebugLoc().isUnknown()) {
DILocation DLT = MF->getDILocation(MI.getDebugLoc());
O << ':' << DLT.getLineNumber();
if (DLT.getColumnNumber() != 0)
O << ':' << DLT.getColumnNumber();
- Newline = true;
+ O << '\n';
}
// Check for spills and reloads
if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
MMO = *MI.memoperands_begin();
- if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Reload";
- Newline = true;
+ O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Reload\n";
}
}
else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
- if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << ' '
- << MMO->getSize() << "-byte Folded Reload";
- Newline = true;
+ << MMO->getSize() << "-byte Folded Reload\n";
}
}
else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
MMO = *MI.memoperands_begin();
- if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Spill";
- Newline = true;
+ O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Spill\n";
}
}
else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
- if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << ' '
- << MMO->getSize() << "-byte Folded Spill";
- Newline = true;
+ << MMO->getSize() << "-byte Folded Spill\n";
}
}
if (TM.getInstrInfo()->isMoveInstr(MI, SrcReg, DstReg,
SrcSubIdx, DstSubIdx)) {
if (MI.getAsmPrinterFlag(ReloadReuse)) {
- if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " Reload Reuse";
+ O << MAI->getCommentString() << " Reload Reuse\n";
}
}
}