diff options
author | Dan Gohman <gohman@apple.com> | 2008-09-25 17:05:24 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-09-25 17:05:24 +0000 |
commit | 78ae76d54c1a523366be7e1c3cde16287e94de5f (patch) | |
tree | 3fea627a04867be8ca3b5efacd1e7435704933bb | |
parent | 73ae9e46e3fe3343f26ab84a0868a828ddba0285 (diff) | |
download | external_llvm-78ae76d54c1a523366be7e1c3cde16287e94de5f.zip external_llvm-78ae76d54c1a523366be7e1c3cde16287e94de5f.tar.gz external_llvm-78ae76d54c1a523366be7e1c3cde16287e94de5f.tar.bz2 |
FastISel support for debug info.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56610 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/CodeGen/FastISel.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 94 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 22 |
4 files changed, 119 insertions, 3 deletions
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 763d702..589e8e4 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -258,6 +258,8 @@ private: bool SelectGetElementPtr(User *I); + bool SelectCall(User *I); + bool SelectBitCast(User *I); bool SelectCast(User *I, ISD::NodeType Opcode); diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index dd7e952..254b1fe 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -11,9 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" @@ -260,6 +264,93 @@ bool FastISel::SelectGetElementPtr(User *I) { return true; } +bool FastISel::SelectCall(User *I) { + Function *F = cast<CallInst>(I)->getCalledFunction(); + if (!F) return false; + + unsigned IID = F->getIntrinsicID(); + switch (IID) { + default: break; + case Intrinsic::dbg_stoppoint: { + DbgStopPointInst *SPI = cast<DbgStopPointInst>(I); + if (MMI && SPI->getContext() && MMI->Verify(SPI->getContext())) { + DebugInfoDesc *DD = MMI->getDescFor(SPI->getContext()); + assert(DD && "Not a debug information descriptor"); + const CompileUnitDesc *CompileUnit = cast<CompileUnitDesc>(DD); + unsigned SrcFile = MMI->RecordSource(CompileUnit); + unsigned Line = SPI->getLine(); + unsigned Col = SPI->getColumn(); + unsigned ID = MMI->RecordSourceLine(Line, Col, SrcFile); + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + BuildMI(MBB, II).addImm(ID); + } + return true; + } + case Intrinsic::dbg_region_start: { + DbgRegionStartInst *RSI = cast<DbgRegionStartInst>(I); + if (MMI && RSI->getContext() && MMI->Verify(RSI->getContext())) { + unsigned ID = MMI->RecordRegionStart(RSI->getContext()); + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + BuildMI(MBB, II).addImm(ID); + } + return true; + } + case Intrinsic::dbg_region_end: { + DbgRegionEndInst *REI = cast<DbgRegionEndInst>(I); + if (MMI && REI->getContext() && MMI->Verify(REI->getContext())) { + unsigned ID = MMI->RecordRegionEnd(REI->getContext()); + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); + BuildMI(MBB, II).addImm(ID); + } + return true; + } + case Intrinsic::dbg_func_start: { + if (!MMI) return true; + DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I); + Value *SP = FSI->getSubprogram(); + if (SP && MMI->Verify(SP)) { + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is + // what (most?) gdb expects. + DebugInfoDesc *DD = MMI->getDescFor(SP); + assert(DD && "Not a debug information descriptor"); + SubprogramDesc *Subprogram = cast<SubprogramDesc>(DD); + const CompileUnitDesc *CompileUnit = Subprogram->getFile(); + unsigned SrcFile = MMI->RecordSource(CompileUnit); + // Record the source line but does create a label. It will be emitted + // at asm emission time. + MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile); + } + return true; + } + case Intrinsic::dbg_declare: { + DbgDeclareInst *DI = cast<DbgDeclareInst>(I); + Value *Variable = DI->getVariable(); + if (MMI && Variable && MMI->Verify(Variable)) { + // Determine the address of the declared object. + Value *Address = DI->getAddress(); + if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address)) + Address = BCI->getOperand(0); + AllocaInst *AI = dyn_cast<AllocaInst>(Address); + // Don't handle byval struct arguments, for example. + if (!AI) break; + DenseMap<const AllocaInst*, int>::iterator SI = + StaticAllocaMap.find(AI); + assert(SI != StaticAllocaMap.end() && "Invalid dbg.declare!"); + int FI = SI->second; + + // Determine the debug globalvariable. + GlobalValue *GV = cast<GlobalVariable>(Variable); + + // Build the DECLARE instruction. + const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE); + BuildMI(MBB, II).addFrameIndex(FI).addGlobalAddress(GV); + } + return true; + } + } + return false; +} + bool FastISel::SelectCast(User *I, ISD::NodeType Opcode) { MVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); MVT DstVT = TLI.getValueType(I->getType()); @@ -424,6 +515,9 @@ FastISel::SelectOperator(User *I, unsigned Opcode) { // Dynamic-sized alloca is not handled yet. return false; + case Instruction::Call: + return SelectCall(I); + case Instruction::BitCast: return SelectBitCast(I); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index ac4a639..b9f1aa4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -246,7 +246,9 @@ static bool isUsedOutsideOfDefiningBlock(Instruction *I) { static bool isOnlyUsedInEntryBlock(Argument *A, bool EnableFastISel) { // With FastISel active, we may be splitting blocks, so force creation // of virtual registers for all non-dead arguments. - if (EnableFastISel) + // Don't force virtual registers for byval arguments though, because + // fast-isel can't handle those in all cases. + if (EnableFastISel && !A->hasByValAttr()) return A->use_empty(); BasicBlock *Entry = A->getParent()->begin(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 9e12a27..cbb1762 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -718,12 +718,27 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, BasicBlock::iterator BI = Begin; // Lower any arguments needed in this block if this is the entry block. - if (LLVMBB == &Fn.getEntryBlock()) + bool SuppressFastISel = false; + if (LLVMBB == &Fn.getEntryBlock()) { LowerArguments(LLVMBB); + // If any of the arguments has the byval attribute, forgo + // fast-isel in the entry block. + if (EnableFastISel) { + unsigned j = 1; + for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); + I != E; ++I, ++j) + if (Fn.paramHasAttr(j, ParamAttr::ByVal)) { + cerr << "FastISel skips entry block due to byval argument"; + SuppressFastISel = true; + break; + } + } + } + // Before doing SelectionDAG ISel, see if FastISel has been requested. // FastISel doesn't support EH landing pads, which require special handling. - if (EnableFastISel && !BB->isLandingPad()) { + if (EnableFastISel && !SuppressFastISel && !BB->isLandingPad()) { if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, MMI, FuncInfo->ValueMap, FuncInfo->MBBMap, @@ -761,6 +776,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, // Then handle certain instructions as single-LLVM-Instruction blocks. if (isa<CallInst>(BI)) { + cerr << "FastISel missed call: "; + BI->dump(); + if (BI->getType() != Type::VoidTy) { unsigned &R = FuncInfo->ValueMap[BI]; if (!R) |