@@ -151,7 +151,7 @@ class SafeStack {
151
151
Value *getStackGuard (IRBuilder<> &IRB, Function &F);
152
152
153
153
// / Load stack guard from the frame and check if it has changed.
154
- void checkStackGuard (IRBuilder<> &IRB, Function &F, ReturnInst &RI,
154
+ void checkStackGuard (IRBuilder<> &IRB, Function &F, Instruction &RI,
155
155
AllocaInst *StackGuardSlot, Value *StackGuard);
156
156
157
157
// / Find all static allocas, dynamic allocas, return instructions and
@@ -160,23 +160,21 @@ class SafeStack {
160
160
void findInsts (Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas,
161
161
SmallVectorImpl<AllocaInst *> &DynamicAllocas,
162
162
SmallVectorImpl<Argument *> &ByValArguments,
163
- SmallVectorImpl<ReturnInst *> &Returns,
163
+ SmallVectorImpl<Instruction *> &Returns,
164
164
SmallVectorImpl<Instruction *> &StackRestorePoints);
165
165
166
166
// / Calculate the allocation size of a given alloca. Returns 0 if the
167
167
// / size can not be statically determined.
168
168
uint64_t getStaticAllocaAllocationSize (const AllocaInst* AI);
169
169
170
170
// / Allocate space for all static allocas in \p StaticAllocas,
171
- // / replace allocas with pointers into the unsafe stack and generate code to
172
- // / restore the stack pointer before all return instructions in \p Returns.
171
+ // / replace allocas with pointers into the unsafe stack.
173
172
// /
174
173
// / \returns A pointer to the top of the unsafe stack after all unsafe static
175
174
// / allocas are allocated.
176
175
Value *moveStaticAllocasToUnsafeStack (IRBuilder<> &IRB, Function &F,
177
176
ArrayRef<AllocaInst *> StaticAllocas,
178
177
ArrayRef<Argument *> ByValArguments,
179
- ArrayRef<ReturnInst *> Returns,
180
178
Instruction *BasePointer,
181
179
AllocaInst *StackGuardSlot);
182
180
@@ -383,7 +381,7 @@ void SafeStack::findInsts(Function &F,
383
381
SmallVectorImpl<AllocaInst *> &StaticAllocas,
384
382
SmallVectorImpl<AllocaInst *> &DynamicAllocas,
385
383
SmallVectorImpl<Argument *> &ByValArguments,
386
- SmallVectorImpl<ReturnInst *> &Returns,
384
+ SmallVectorImpl<Instruction *> &Returns,
387
385
SmallVectorImpl<Instruction *> &StackRestorePoints) {
388
386
for (Instruction &I : instructions (&F)) {
389
387
if (auto AI = dyn_cast<AllocaInst>(&I)) {
@@ -401,7 +399,10 @@ void SafeStack::findInsts(Function &F,
401
399
DynamicAllocas.push_back (AI);
402
400
}
403
401
} else if (auto RI = dyn_cast<ReturnInst>(&I)) {
404
- Returns.push_back (RI);
402
+ if (CallInst *CI = I.getParent ()->getTerminatingMustTailCall ())
403
+ Returns.push_back (CI);
404
+ else
405
+ Returns.push_back (RI);
405
406
} else if (auto CI = dyn_cast<CallInst>(&I)) {
406
407
// setjmps require stack restore.
407
408
if (CI->getCalledFunction () && CI->canReturnTwice ())
@@ -465,7 +466,7 @@ SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F,
465
466
return DynamicTop;
466
467
}
467
468
468
- void SafeStack::checkStackGuard (IRBuilder<> &IRB, Function &F, ReturnInst &RI,
469
+ void SafeStack::checkStackGuard (IRBuilder<> &IRB, Function &F, Instruction &RI,
469
470
AllocaInst *StackGuardSlot, Value *StackGuard) {
470
471
Value *V = IRB.CreateLoad (StackPtrTy, StackGuardSlot);
471
472
Value *Cmp = IRB.CreateICmpNE (StackGuard, V);
@@ -490,8 +491,8 @@ void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, ReturnInst &RI,
490
491
// / prologue into a local variable and restore it in the epilogue.
491
492
Value *SafeStack::moveStaticAllocasToUnsafeStack (
492
493
IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas,
493
- ArrayRef<Argument *> ByValArguments, ArrayRef<ReturnInst *> Returns ,
494
- Instruction *BasePointer, AllocaInst *StackGuardSlot) {
494
+ ArrayRef<Argument *> ByValArguments, Instruction *BasePointer ,
495
+ AllocaInst *StackGuardSlot) {
495
496
if (StaticAllocas.empty () && ByValArguments.empty ())
496
497
return BasePointer;
497
498
@@ -759,7 +760,7 @@ bool SafeStack::run() {
759
760
SmallVector<AllocaInst *, 16 > StaticAllocas;
760
761
SmallVector<AllocaInst *, 4 > DynamicAllocas;
761
762
SmallVector<Argument *, 4 > ByValArguments;
762
- SmallVector<ReturnInst *, 4 > Returns;
763
+ SmallVector<Instruction *, 4 > Returns;
763
764
764
765
// Collect all points where stack gets unwound and needs to be restored
765
766
// This is only necessary because the runtime (setjmp and unwind code) is
@@ -812,17 +813,16 @@ bool SafeStack::run() {
812
813
StackGuardSlot = IRB.CreateAlloca (StackPtrTy, nullptr );
813
814
IRB.CreateStore (StackGuard, StackGuardSlot);
814
815
815
- for (ReturnInst *RI : Returns) {
816
+ for (Instruction *RI : Returns) {
816
817
IRBuilder<> IRBRet (RI);
817
818
checkStackGuard (IRBRet, F, *RI, StackGuardSlot, StackGuard);
818
819
}
819
820
}
820
821
821
822
// The top of the unsafe stack after all unsafe static allocas are
822
823
// allocated.
823
- Value *StaticTop =
824
- moveStaticAllocasToUnsafeStack (IRB, F, StaticAllocas, ByValArguments,
825
- Returns, BasePointer, StackGuardSlot);
824
+ Value *StaticTop = moveStaticAllocasToUnsafeStack (
825
+ IRB, F, StaticAllocas, ByValArguments, BasePointer, StackGuardSlot);
826
826
827
827
// Safe stack object that stores the current unsafe stack top. It is updated
828
828
// as unsafe dynamic (non-constant-sized) allocas are allocated and freed.
@@ -838,7 +838,7 @@ bool SafeStack::run() {
838
838
DynamicAllocas);
839
839
840
840
// Restore the unsafe stack pointer before each return.
841
- for (ReturnInst *RI : Returns) {
841
+ for (Instruction *RI : Returns) {
842
842
IRB.SetInsertPoint (RI);
843
843
IRB.CreateStore (BasePointer, UnsafeStackPtr);
844
844
}
0 commit comments