FastISel support for debug info.
authorDan Gohman <gohman@apple.com>
Thu, 25 Sep 2008 17:05:24 +0000 (17:05 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 25 Sep 2008 17:05:24 +0000 (17:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56610 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/FastISel.h
lib/CodeGen/SelectionDAG/FastISel.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 763d7029e66284af7ea3fb2fb793fb68d3633eb2..589e8e41bb1482ee2dbfbc782197530419f652f8 100644 (file)
@@ -258,6 +258,8 @@ private:
 
   bool SelectGetElementPtr(User *I);
 
+  bool SelectCall(User *I);
+
   bool SelectBitCast(User *I);
   
   bool SelectCast(User *I, ISD::NodeType Opcode);
index dd7e95294f116d3e54a8d3224b24fb9f364014c7..254b1fe42ccd5ec0e2bf1727ab6be9b6c637790d 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#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);
 
index ac4a639ea31b01470b9773cf035ecf9c6dc70fd3..b9f1aa45078ecca5862a0708d2f2ce0f5d2f7da6 100644 (file)
@@ -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();
index 9e12a272ad6e4c6833ecdb3282bdae0e0fc54ab8..cbb1762e26b07a5e8ed90222874ed760bd8cd9ed 100644 (file)
@@ -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)