annotate gen/passes/GarbageCollect2Stack.cpp @ 1291:875afb7a93b6

Factor out some constants into the header so producers and consumers of metadata stay in sync (and are more readable).
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 02 May 2009 20:42:58 +0200
parents 91d9386d4a5a
children 0e79fb40c4d0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
1 //===- GarbageCollect2Stack - Optimize calls to the D garbage collector ---===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
2 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
3 // The LLVM D Compiler
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
4 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
7 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
9 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
10 // This file attempts to turn allocations on the garbage-collected heap into
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
11 // stack allocations.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
12 //
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
13 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
14
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
15 #include "gen/metadata.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
16
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
17 // This pass doesn't work without metadata, so #ifdef it out entirely if the
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
18 // LLVM version in use doesn't support it.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
19 #ifdef USE_METADATA
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
20
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
21
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
22 #define DEBUG_TYPE "dgc2stack"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
23
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
24 #include "Passes.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
25
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
26 #include "llvm/Pass.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
27 #include "llvm/Module.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
28 #include "llvm/Support/CallSite.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
29 #include "llvm/Support/CommandLine.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
30 #include "llvm/Support/IRBuilder.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
31 #include "llvm/Analysis/CaptureTracking.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
32 #include "llvm/Analysis/LoopInfo.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
33 #include "llvm/Target/TargetData.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
34 #include "llvm/ADT/StringMap.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
35 #include "llvm/ADT/Statistic.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
36 #include "llvm/Support/Compiler.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
37 #include "llvm/Support/Debug.h"
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
38 using namespace llvm;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
39
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
40 STATISTIC(NumGcToStack, "Number of GC calls promoted to stack allocations");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
41 STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
42
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
43 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
44 // GarbageCollect2Stack Pass Implementation
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
45 //===----------------------------------------------------------------------===//
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
46
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
47 namespace {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
48 struct FunctionInfo {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
49 unsigned TypeInfoArgNr;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
50 bool SafeToDelete;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
51
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
52 FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
53 : TypeInfoArgNr(typeInfoArgNr), SafeToDelete(safeToDelete) {}
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
54
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
55 Value* getArraySize(CallSite CS) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
56 return 0;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
57 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
58 };
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
59
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
60 /// This pass replaces GC calls with alloca's
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
61 ///
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
62 class VISIBILITY_HIDDEN GarbageCollect2Stack : public FunctionPass {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
63 StringMap<FunctionInfo*> KnownFunctions;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
64 Module* M;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
65
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
66 public:
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
67 static char ID; // Pass identification
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
68 GarbageCollect2Stack() : FunctionPass(&ID) {}
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
69
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
70 bool doInitialization(Module &M);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
71
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
72 bool runOnFunction(Function &F);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
73
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
74 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
75 AU.addRequired<TargetData>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
76 AU.addRequired<LoopInfo>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
77 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
78
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
79 private:
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
80 const Type* getTypeFor(Value* typeinfo);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
81 };
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
82 char GarbageCollect2Stack::ID = 0;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
83 } // end anonymous namespace.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
84
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
85 static RegisterPass<GarbageCollect2Stack>
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
86 X("dgc2stack", "Promote (GC'ed) heap allocations to stack");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
87
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
88 // Public interface to the pass.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
89 FunctionPass *createGarbageCollect2Stack() {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
90 return new GarbageCollect2Stack();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
91 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
92
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
93 bool GarbageCollect2Stack::doInitialization(Module &M) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
94 this->M = &M;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
95 KnownFunctions["_d_allocmemoryT"] = new FunctionInfo(0, true);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
96 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
97
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
98 /// runOnFunction - Top level algorithm.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
99 ///
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
100 bool GarbageCollect2Stack::runOnFunction(Function &F) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
101 DEBUG(DOUT << "Running on function " << F.getName() << '\n');
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
102
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
103 const TargetData &TD = getAnalysis<TargetData>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
104 const LoopInfo &LI = getAnalysis<LoopInfo>();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
105
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
106 BasicBlock& Entry = F.getEntryBlock();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
107
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
108 IRBuilder<> AllocaBuilder(&Entry, Entry.begin());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
109
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
110 bool Changed = false;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
111 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
112 // We don't yet have sufficient analysis to properly determine if
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
113 // allocations will be unreferenced when the loop returns to their
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
114 // allocation point, so we're playing it safe by ignoring allocations
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
115 // in loops.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
116 // TODO: Analyze loops too...
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
117 if (LI.getLoopFor(BB)) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
118 DEBUG(DOUT << "Skipping loop block " << *BB << '\n');
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
119 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
120 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
121
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
122 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
123 // Ignore non-calls.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
124 Instruction* Inst = I++;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
125 CallSite CS = CallSite::get(Inst);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
126 if (!CS.getInstruction())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
127 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
128
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
129 // Ignore indirect calls and calls to non-external functions.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
130 Function *Callee = CS.getCalledFunction();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
131 if (Callee == 0 || !Callee->isDeclaration() ||
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
132 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
133 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
134
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
135 // Ignore unknown calls.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
136 const char *CalleeName = Callee->getNameStart();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
137 StringMap<FunctionInfo*>::iterator OMI =
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
138 KnownFunctions.find(CalleeName, CalleeName+Callee->getNameLen());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
139 if (OMI == KnownFunctions.end()) continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
140
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
141 assert(isa<PointerType>(Inst->getType())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
142 && "GC function doesn't return a pointer?");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
143
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
144 FunctionInfo* info = OMI->getValue();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
145
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
146 if (Inst->use_empty() && info->SafeToDelete) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
147 Changed = true;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
148 NumDeleted++;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
149 Inst->eraseFromParent();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
150 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
151 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
152
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
153 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
154
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
155 if (PointerMayBeCaptured(Inst, true)) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
156 DEBUG(DOUT << ">> is captured :(\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
157 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
158 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
159 DEBUG(DOUT << ">> is not captured :)\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
160
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
161 Value* TypeInfo = CS.getArgument(info->TypeInfoArgNr);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
162 const Type* Ty = getTypeFor(TypeInfo);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
163 if (!Ty) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
164 DEBUG(DOUT << ">> Couldn't find valid TypeInfo metadata :(\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
165 continue;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
166 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
167
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
168 // Let's alloca this!
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
169 Changed = true;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
170 NumGcToStack++;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
171
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
172 Value* arrSize = info->getArraySize(CS);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
173 Value* newVal = AllocaBuilder.CreateAlloca(Ty, arrSize, ".nongc_mem");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
174
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
175 if (newVal->getType() != Inst->getType())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
176 newVal = AllocaBuilder.CreateBitCast(newVal, Inst->getType());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
177
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
178 Inst->replaceAllUsesWith(newVal);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
179
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
180 if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
181 Invoke->getUnwindDest()->removePredecessor(Invoke->getParent());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
182 // Create a branch to the "normal" destination.
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
183 BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
184 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
185 Inst->eraseFromParent();
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
186 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
187 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
188 return Changed;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
189 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
190
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
191 const Type* GarbageCollect2Stack::getTypeFor(Value* typeinfo) {
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
192 GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
193 if (!ti_global)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
194 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
195
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
196 DEBUG(DOUT << ">> Found typeinfo init\n";
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
197 DOUT << ">> Value: " << *ti_global << "\n";
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
198 DOUT << ">> Name: " << ti_global->getNameStr() << "\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
199
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
200 std::string metaname = TD_PREFIX;
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
201 metaname.append(ti_global->getNameStart(), ti_global->getNameEnd());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
202
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
203 DEBUG(DOUT << ">> Looking for global named " << metaname << "\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
204
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
205 GlobalVariable* global = M->getGlobalVariable(metaname);
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
206 DEBUG(DOUT << ">> global: " << global->getInitializer() << "\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
207 if (!global || !global->hasInitializer())
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
208 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
209
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
210 DEBUG(DOUT << ">> Found metadata global\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
211
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
212 MDNode* node = dyn_cast<MDNode>(global->getInitializer());
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
213 if (!node)
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
214 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
215
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
216 DEBUG(DOUT << ">> Found metadata node\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
217
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
218 if (node->getNumOperands() != TD_NumFields ||
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
219 node->getOperand(TD_Confirm)->stripPointerCasts() != ti_global)
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
220 return NULL;
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
221
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
222 DEBUG(DOUT << ">> Validated metadata node\n");
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
223
1291
875afb7a93b6 Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents: 1285
diff changeset
224 return node->getOperand(TD_Type)->getType();
1285
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
225 }
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
226
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
227
91d9386d4a5a Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
228 #endif //USE_METADATA