Enabling the target-independent garbage collection infrastructure by hooking it
authorGordon Henriksen <gordonhenriksen@mac.com>
Mon, 7 Jan 2008 01:30:38 +0000 (01:30 +0000)
committerGordon Henriksen <gordonhenriksen@mac.com>
Mon, 7 Jan 2008 01:30:38 +0000 (01:30 +0000)
up to the various compiler pipelines.

This doesn't actually add support for any GC algorithms, which means it
temporarily breaks a few tests. To be fixed shortly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45669 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
include/llvm/CodeGen/SelectionDAGISel.h
lib/CodeGen/AsmPrinter.cpp
lib/CodeGen/README.txt
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/MSIL/MSILWriter.cpp

index e1be58ee5688ece34b4415cf7096e7e59e26c0b0..3d1344e2a25c04940b96128e6bc62b61da4905c9 100644 (file)
@@ -118,6 +118,10 @@ namespace llvm {
     std::string getCurrentFunctionEHName(const MachineFunction *MF);
 
   protected:
+    /// getAnalysisUsage - Record analysis usage.
+    /// 
+    void getAnalysisUsage(AnalysisUsage &AU) const;
+    
     /// doInitialization - Set up the AsmPrinter when we are working on a new
     /// module.  If your pass overrides this, it must make sure to explicitly
     /// call this implementation.
index 7ca239a5971a6e500bd2b1ae8439de830052bca6..82542d1bb4964e5b234ab3c3f8d187df2715d6b6 100644 (file)
@@ -30,6 +30,7 @@ namespace llvm {
   class TargetLowering;
   class FunctionLoweringInfo;
   class HazardRecognizer;
+  class CollectorMetadata;
  
 /// SelectionDAGISel - This is the common base class used for SelectionDAG-based
 /// pattern-matching instruction selectors.
@@ -42,10 +43,11 @@ public:
   AliasAnalysis *AA;
   std::vector<SDNode*> TopOrder;
   unsigned DAGSize;
+  CollectorMetadata *GCI;
   static char ID;
 
   explicit SelectionDAGISel(TargetLowering &tli) : 
-    FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0) {}
+    FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0), GCI(0) {}
   
   TargetLowering &getTargetLowering() { return TLI; }
 
index b3643129d9f2e31364ee2582925e7b8aba33e192..bb66bd2ad5c3b0dbd3abce94d53ec5858c54785b 100644 (file)
@@ -16,6 +16,8 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Constants.h"
 #include "llvm/Module.h"
+#include "llvm/CodeGen/Collector.h"
+#include "llvm/CodeGen/CollectorMetadata.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -94,9 +96,20 @@ void AsmPrinter::SwitchToDataSection(const char *NewSection,
 }
 
 
+void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
+  MachineFunctionPass::getAnalysisUsage(AU);
+  AU.addRequired<CollectorModuleMetadata>();
+}
+
 bool AsmPrinter::doInitialization(Module &M) {
   Mang = new Mangler(M, TAI->getGlobalPrefix());
   
+  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
+  assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
+  for (CollectorModuleMetadata::iterator I = CMM->begin(),
+                                         E = CMM->end(); I != E; ++I)
+    (*I)->beginAssembly(O, *this, *TAI);
+  
   if (!M.getModuleInlineAsm().empty())
     O << TAI->getCommentString() << " Start of file scope inline assembly\n"
       << M.getModuleInlineAsm()
@@ -158,6 +171,12 @@ bool AsmPrinter::doFinalization(Module &M) {
     }
   }
 
+  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
+  assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
+  for (CollectorModuleMetadata::iterator I = CMM->end(),
+                                         E = CMM->begin(); I != E; )
+    (*--I)->finishAssembly(O, *this, *TAI);
+
   delete Mang; Mang = 0;
   return false;
 }
index fc59cdf86401aa89298136b82892c1ca8fa00814..a05c08b1285ca3f13fbe341e9dc01c6c16970677 100644 (file)
@@ -187,3 +187,8 @@ revisited. The check is there to work around a misuse of directives in inline
 assembly.
 
 //===---------------------------------------------------------------------===//
+
+It would be good to detect collector/target compatibility instead of silently
+doing the wrong thing.
+
+//===---------------------------------------------------------------------===//
index 13d3f9720feb5ad615e1acc136b41a1b57ad7dbe..69c7b2c7b9593a28a67b1c7a6106dbc0eb25aad6 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/Intrinsics.h"
 #include "llvm/IntrinsicInst.h"
 #include "llvm/ParameterAttributes.h"
+#include "llvm/CodeGen/Collector.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -426,12 +427,16 @@ public:
   /// FuncInfo - Information about the function as a whole.
   ///
   FunctionLoweringInfo &FuncInfo;
+  
+  /// GCI - Garbage collection metadata for the function.
+  CollectorMetadata *GCI;
 
   SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli,
                        AliasAnalysis &aa,
-                       FunctionLoweringInfo &funcinfo)
+                       FunctionLoweringInfo &funcinfo,
+                       CollectorMetadata *gci)
     : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa),
-      FuncInfo(funcinfo) {
+      FuncInfo(funcinfo), GCI(gci) {
   }
 
   /// getRoot - Return the current virtual root of the Selection DAG.
@@ -2907,6 +2912,22 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     DAG.setRoot(Tmp.getValue(1));
     return 0;
   }
+
+  case Intrinsic::gcroot:
+    if (GCI) {
+      Value *Alloca = I.getOperand(1);
+      Constant *TypeMap = cast<Constant>(I.getOperand(2));
+      
+      FrameIndexSDNode *FI = cast<FrameIndexSDNode>(getValue(Alloca).Val);
+      GCI->addStackRoot(FI->getIndex(), TypeMap);
+    }
+    return 0;
+
+  case Intrinsic::gcread:
+  case Intrinsic::gcwrite:
+    assert(0 && "Collector failed to lower gcread/gcwrite intrinsics!");
+    return 0;
+
   case Intrinsic::flt_rounds: {
     setValue(&I, DAG.getNode(ISD::FLT_ROUNDS, MVT::i32));
     return 0;
@@ -4368,6 +4389,7 @@ unsigned SelectionDAGISel::MakeReg(MVT::ValueType VT) {
 
 void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<AliasAnalysis>();
+  AU.addRequired<CollectorModuleMetadata>();
   AU.setPreservesAll();
 }
 
@@ -4378,6 +4400,10 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
   AA = &getAnalysis<AliasAnalysis>();
 
   MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
+  if (MF.getFunction()->hasCollector())
+    GCI = &getAnalysis<CollectorModuleMetadata>().get(*MF.getFunction());
+  else
+    GCI = 0;
   RegInfo = &MF.getRegInfo();
   DOUT << "\n\n\n=== " << Fn.getName() << "\n";
 
@@ -4515,7 +4541,7 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG,
 void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
        std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
                                          FunctionLoweringInfo &FuncInfo) {
-  SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo);
+  SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GCI);
 
   std::vector<SDOperand> UnorderedChains;
 
@@ -4774,7 +4800,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
     if (!BitTestCases[i].Emitted) {
       SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &HSDAG;
-      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo);
+      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
       BB = BitTestCases[i].Parent;
       HSDL.setCurrentBasicBlock(BB);
@@ -4787,7 +4813,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
     for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
       SelectionDAG BSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &BSDAG;
-      SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo);
+      SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
       BB = BitTestCases[i].Cases[j].ThisBB;
       BSDL.setCurrentBasicBlock(BB);
@@ -4844,7 +4870,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
     if (!JTCases[i].first.Emitted) {
       SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &HSDAG;
-      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo);
+      SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
       BB = JTCases[i].first.HeaderBB;
       HSDL.setCurrentBasicBlock(BB);
@@ -4856,7 +4882,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
     
     SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &JSDAG;
-    SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo);
+    SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI);
     // Set the current basic block to the mbb we wish to insert the code into
     BB = JTCases[i].second.MBB;
     JSDL.setCurrentBasicBlock(BB);
@@ -4904,7 +4930,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
   for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
     SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &SDAG;
-    SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo);
+    SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);
     
     // Set the current basic block to the mbb we wish to insert the code into
     BB = SwitchCases[i].ThisBB;
index d695e44bcdf6ce826d85b58a47284fffa8935dba..f4e9e341528340e90fc2d05a548bfc2df18aca02 100644 (file)
@@ -28,6 +28,7 @@
 #include "llvm/Analysis/ConstantsScanner.h"
 #include "llvm/Analysis/FindUsedTypes.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/IntrinsicLowering.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Target/TargetMachineRegistry.h"
@@ -2946,11 +2947,12 @@ bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
                                               bool Fast) {
   if (FileType != TargetMachine::AssemblyFile) return true;
 
-  PM.add(createLowerGCPass());
+  PM.add(createGCLoweringPass());
   PM.add(createLowerAllocationsPass(true));
   PM.add(createLowerInvokePass());
   PM.add(createCFGSimplificationPass());   // clean up after lower invoke.
   PM.add(new CBackendNameAllUsedStructsAndMergeFunctions());
   PM.add(new CWriter(o));
+  PM.add(createCollectorMetadataDeleter());
   return false;
 }
index 141bc4b6c7065d0ecfd807c63dcdd5a349293c37..72ccc3a2c394ec37606e717a40d126f36d6aa5e8 100644 (file)
@@ -24,6 +24,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/CodeGen/Passes.h"
 
 namespace {
   // TargetMachine for the MSIL 
@@ -1647,12 +1648,13 @@ bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
 {
   if (FileType != TargetMachine::AssemblyFile) return true;
   MSILWriter* Writer = new MSILWriter(o);
-  PM.add(createLowerGCPass());
+  PM.add(createGCLoweringPass());
   PM.add(createLowerAllocationsPass(true));
   // FIXME: Handle switch trougth native IL instruction "switch"
   PM.add(createLowerSwitchPass());
   PM.add(createCFGSimplificationPass());
   PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
   PM.add(Writer);
+  PM.add(createCollectorMetadataDeleter());
   return false;
 }