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 }