aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-09-25 17:05:24 +0000
committerDan Gohman <gohman@apple.com>2008-09-25 17:05:24 +0000
commit78ae76d54c1a523366be7e1c3cde16287e94de5f (patch)
tree3fea627a04867be8ca3b5efacd1e7435704933bb
parent73ae9e46e3fe3343f26ab84a0868a828ddba0285 (diff)
downloadexternal_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.h2
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp94
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp22
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)