Mercurial > projects > ldc
annotate gen/passes/GarbageCollect2Stack.cpp @ 1298:7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Fixes #284.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Mon, 04 May 2009 12:08:30 +0200 |
parents | 8e8552601ecd |
children | 8215dbf0e09f |
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" |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
32 #include "llvm/Analysis/ValueTracking.h" |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
33 #include "llvm/Analysis/LoopInfo.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
34 #include "llvm/Target/TargetData.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
35 #include "llvm/ADT/StringMap.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
36 #include "llvm/ADT/Statistic.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
37 #include "llvm/Support/Compiler.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
38 #include "llvm/Support/Debug.h" |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
39 using namespace llvm; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
41 STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas"); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
42 STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas"); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
43 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
|
44 |
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 // GarbageCollect2Stack Pass Implementation |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
47 //===----------------------------------------------------------------------===// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
48 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
49 namespace { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
50 struct FunctionInfo { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
51 unsigned TypeInfoArgNr; |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
52 int ArrSizeArgNr; |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
53 bool SafeToDelete; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
54 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
55 FunctionInfo(unsigned typeInfoArgNr, int arrSizeArgNr, bool safeToDelete) |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
56 : TypeInfoArgNr(typeInfoArgNr), ArrSizeArgNr(arrSizeArgNr), |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
57 SafeToDelete(safeToDelete) {} |
1285
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; |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
95 KnownFunctions["_d_allocmemoryT"] = new FunctionInfo(0, -1, true); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
96 KnownFunctions["_d_newarrayvT"] = new FunctionInfo(0, 1, true); |
1285
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 |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
99 static void RemoveCall(Instruction* Inst) { |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
100 if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) { |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
101 // If this was an invoke instruction, we need to do some extra |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
102 // work to preserve the control flow. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
103 |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
104 // First notify the exception landing pad block that we won't be |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
105 // going there anymore. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
106 Invoke->getUnwindDest()->removePredecessor(Invoke->getParent()); |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
107 // Create a branch to the "normal" destination. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
108 BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
109 } |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
110 // Remove the runtime call. |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
111 Inst->eraseFromParent(); |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
112 } |
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
113 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
114 /// runOnFunction - Top level algorithm. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
115 /// |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
116 bool GarbageCollect2Stack::runOnFunction(Function &F) { |
1295
0e79fb40c4d0
Remove some overly verbose debug output
Frits van Bommel <fvbommel wxs.nl>
parents:
1291
diff
changeset
|
117 DEBUG(DOUT << "Running -dgc2stack on function " << F.getName() << '\n'); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
118 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
119 TargetData &TD = getAnalysis<TargetData>(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
120 const LoopInfo &LI = getAnalysis<LoopInfo>(); |
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 BasicBlock& Entry = F.getEntryBlock(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
123 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
124 IRBuilder<> AllocaBuilder(&Entry, Entry.begin()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
125 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
126 bool Changed = false; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
127 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
|
128 // 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
|
129 // 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
|
130 // 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
|
131 // in loops. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 // TODO: Analyze loops too... |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
133 if (LI.getLoopFor(BB)) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
134 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
135 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
136 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
137 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
|
138 // Ignore non-calls. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
139 Instruction* Inst = I++; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
140 CallSite CS = CallSite::get(Inst); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
141 if (!CS.getInstruction()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
142 continue; |
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 // 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
|
145 Function *Callee = CS.getCalledFunction(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
146 if (Callee == 0 || !Callee->isDeclaration() || |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
147 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
148 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
149 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
150 // Ignore unknown calls. |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
151 const char *CalleeName = Callee->getNameStart(); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
152 StringMap<FunctionInfo*>::iterator OMI = |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
153 KnownFunctions.find(CalleeName, CalleeName+Callee->getNameLen()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
154 if (OMI == KnownFunctions.end()) continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
155 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
156 assert(isa<PointerType>(Inst->getType()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
157 && "GC function doesn't return a pointer?"); |
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 FunctionInfo* info = OMI->getValue(); |
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 if (Inst->use_empty() && info->SafeToDelete) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
162 Changed = true; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
163 NumDeleted++; |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
164 RemoveCall(Inst); |
1285
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 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
169 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
170 if (PointerMayBeCaptured(Inst, true)) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
171 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
172 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
173 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
174 Value* TypeInfo = CS.getArgument(info->TypeInfoArgNr); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 const Type* Ty = getTypeFor(TypeInfo); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
176 if (!Ty) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
177 continue; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
178 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
179 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
180 Value* arrSize = 0; |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
181 if (info->ArrSizeArgNr != -1) { |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
182 arrSize = CS.getArgument(info->ArrSizeArgNr); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
183 const IntegerType* SizeType = |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
184 dyn_cast<IntegerType>(arrSize->getType()); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
185 if (!SizeType) |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
186 continue; |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
187 unsigned bits = SizeType->getBitWidth(); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
188 if (bits > 32) { |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
189 // The array size of an alloca must be an i32, so make sure |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
190 // the conversion is safe. |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
191 APInt Mask = APInt::getHighBitsSet(bits, bits - 32); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
192 APInt KnownZero(bits, 0), KnownOne(bits, 0); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
193 ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &TD); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
194 if ((KnownZero & Mask) != Mask) |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
195 continue; |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
196 } |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
197 // Extract the element type from the array type. |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
198 const StructType* ArrTy = dyn_cast<StructType>(Ty); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
199 assert(ArrTy && "Dynamic array type not a struct?"); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
200 assert(isa<IntegerType>(ArrTy->getElementType(0))); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
201 const PointerType* PtrTy = |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
202 cast<PointerType>(ArrTy->getElementType(1)); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
203 Ty = PtrTy->getElementType(); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
204 } |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
205 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
206 // Let's alloca this! |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
207 Changed = true; |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
208 |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
209 IRBuilder<> Builder(BB, I); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
210 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
211 // If the allocation is of constant size it's best to put it in the |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
212 // entry block, so do so if we're not already there. |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
213 // For dynamically-sized allocations it's best to avoid the overhead |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
214 // of allocating them if possible, so leave those where they are. |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
215 // While we're at it, update statistics too. |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
216 if (!arrSize || isa<Constant>(arrSize)) { |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
217 if (&*BB != &Entry) |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
218 Builder = AllocaBuilder; |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
219 NumGcToStack++; |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
220 } else { |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
221 NumToDynSize++; |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
222 } |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
223 |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
224 // Convert array size to 32 bits if necessary |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
225 if (arrSize) |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
226 arrSize = Builder.CreateIntCast(arrSize, Type::Int32Ty, false); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
227 |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
228 Value* newVal = Builder.CreateAlloca(Ty, arrSize, ".nongc_mem"); |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
229 |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
230 // Make sure the type is the same as it was before, and replace all |
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
231 // uses of the runtime call with the alloca. |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
232 if (newVal->getType() != Inst->getType()) |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
233 newVal = Builder.CreateBitCast(newVal, Inst->getType()); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
234 Inst->replaceAllUsesWith(newVal); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
235 |
1298
7e303f9f16c7
Don't forget to update the control flow when deleting an invoke.
Frits van Bommel <fvbommel wxs.nl>
parents:
1297
diff
changeset
|
236 RemoveCall(Inst); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
237 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
238 } |
1297
8e8552601ecd
Stack promotion for _d_newarrayvT. Array literals, concatenations (a ~ b) and
Frits van Bommel <fvbommel wxs.nl>
parents:
1295
diff
changeset
|
239 |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
240 return Changed; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
241 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
242 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
243 const Type* GarbageCollect2Stack::getTypeFor(Value* typeinfo) { |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
244 GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
245 if (!ti_global) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
246 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
247 |
1291
875afb7a93b6
Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents:
1285
diff
changeset
|
248 std::string metaname = TD_PREFIX; |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
249 metaname.append(ti_global->getNameStart(), ti_global->getNameEnd()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
250 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
251 GlobalVariable* global = M->getGlobalVariable(metaname); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
252 if (!global || !global->hasInitializer()) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
253 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
254 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
255 MDNode* node = dyn_cast<MDNode>(global->getInitializer()); |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
256 if (!node) |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
257 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
258 |
1291
875afb7a93b6
Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents:
1285
diff
changeset
|
259 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
|
260 node->getOperand(TD_Confirm)->stripPointerCasts() != ti_global) |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
261 return NULL; |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 |
1291
875afb7a93b6
Factor out some constants into the header so producers and consumers of
Frits van Bommel <fvbommel wxs.nl>
parents:
1285
diff
changeset
|
263 return node->getOperand(TD_Type)->getType(); |
1285
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 } |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
265 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
266 |
91d9386d4a5a
Implement another D-specific pass: -dgc2stack
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
267 #endif //USE_METADATA |