Mercurial > projects > ldc
comparison 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 |
comparison
equal
deleted
inserted
replaced
1297:8e8552601ecd | 1298:7e303f9f16c7 |
---|---|
94 this->M = &M; | 94 this->M = &M; |
95 KnownFunctions["_d_allocmemoryT"] = new FunctionInfo(0, -1, true); | 95 KnownFunctions["_d_allocmemoryT"] = new FunctionInfo(0, -1, true); |
96 KnownFunctions["_d_newarrayvT"] = new FunctionInfo(0, 1, true); | 96 KnownFunctions["_d_newarrayvT"] = new FunctionInfo(0, 1, true); |
97 } | 97 } |
98 | 98 |
99 static void RemoveCall(Instruction* Inst) { | |
100 if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) { | |
101 // If this was an invoke instruction, we need to do some extra | |
102 // work to preserve the control flow. | |
103 | |
104 // First notify the exception landing pad block that we won't be | |
105 // going there anymore. | |
106 Invoke->getUnwindDest()->removePredecessor(Invoke->getParent()); | |
107 // Create a branch to the "normal" destination. | |
108 BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); | |
109 } | |
110 // Remove the runtime call. | |
111 Inst->eraseFromParent(); | |
112 } | |
113 | |
99 /// runOnFunction - Top level algorithm. | 114 /// runOnFunction - Top level algorithm. |
100 /// | 115 /// |
101 bool GarbageCollect2Stack::runOnFunction(Function &F) { | 116 bool GarbageCollect2Stack::runOnFunction(Function &F) { |
102 DEBUG(DOUT << "Running -dgc2stack on function " << F.getName() << '\n'); | 117 DEBUG(DOUT << "Running -dgc2stack on function " << F.getName() << '\n'); |
103 | 118 |
144 FunctionInfo* info = OMI->getValue(); | 159 FunctionInfo* info = OMI->getValue(); |
145 | 160 |
146 if (Inst->use_empty() && info->SafeToDelete) { | 161 if (Inst->use_empty() && info->SafeToDelete) { |
147 Changed = true; | 162 Changed = true; |
148 NumDeleted++; | 163 NumDeleted++; |
149 Inst->eraseFromParent(); | 164 RemoveCall(Inst); |
150 continue; | 165 continue; |
151 } | 166 } |
152 | 167 |
153 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst); | 168 DEBUG(DOUT << "GarbageCollect2Stack inspecting: " << *Inst); |
154 | 169 |
216 // uses of the runtime call with the alloca. | 231 // uses of the runtime call with the alloca. |
217 if (newVal->getType() != Inst->getType()) | 232 if (newVal->getType() != Inst->getType()) |
218 newVal = Builder.CreateBitCast(newVal, Inst->getType()); | 233 newVal = Builder.CreateBitCast(newVal, Inst->getType()); |
219 Inst->replaceAllUsesWith(newVal); | 234 Inst->replaceAllUsesWith(newVal); |
220 | 235 |
221 // If this was an invoke instruction, update the control flow. | 236 RemoveCall(Inst); |
222 if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) { | |
223 // Notify the exception landing pad block that we won't be | |
224 // going there anymore. | |
225 Invoke->getUnwindDest()->removePredecessor(Invoke->getParent()); | |
226 // Create a branch to the "normal" destination. | |
227 BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); | |
228 } | |
229 | |
230 // Finally, remove the runtime call. | |
231 Inst->eraseFromParent(); | |
232 } | 237 } |
233 } | 238 } |
234 | 239 |
235 return Changed; | 240 return Changed; |
236 } | 241 } |