llvm.org GIT mirror llvm / 110c835
Make DAE not wipe out attributes on calls, and not drop return attributes on the floor. In the case of a call to a varargs function where the varargs arguments are being removed, any call attributes on those arguments need to be dropped. I didn't do this because I plan to make it illegal to have such attributes (see next patch). With this change, compiling the gcc filter2 eh test at -O0 and then running opt -std-compile-opts on it results in a correctly working program (compiling at -O1 or higher results in the test failing due to a problem with how we output eh info into the IR). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45285 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 11 years ago
3 changed file(s) with 75 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
4949 const uint16_t Informative = NoReturn | NoUnwind | NoAlias |
5050 ReadNone | ReadOnly;
5151
52 /// The following attribute sets are used by the verifier:
53
5452 /// @brief Attributes that only apply to function parameters.
5553 const uint16_t ParameterOnly = ByVal | InReg | Nest | StructRet;
5654
6260
6361 /// @brief Attributes that only apply to pointers.
6462 const uint16_t PointerTypeOnly = ByVal | Nest | NoAlias | StructRet;
63
64 /// @brief Attributes that do not apply to void type function return values.
65 const uint16_t VoidTypeIncompatible = IntegerTypeOnly | PointerTypeOnly |
66 ParameterOnly;
6567
6668 /// @brief Attributes that are mutually incompatible.
6769 const uint16_t MutuallyIncompatible[3] = {
121121 bool DAE::DeleteDeadVarargs(Function &Fn) {
122122 assert(Fn.getFunctionType()->isVarArg() && "Function isn't varargs!");
123123 if (Fn.isDeclaration() || !Fn.hasInternalLinkage()) return false;
124
124
125125 // Ensure that the function is only directly called.
126126 for (Value::use_iterator I = Fn.use_begin(), E = Fn.use_end(); I != E; ++I) {
127127 // If this use is anything other than a call site, give up.
128128 CallSite CS = CallSite::get(*I);
129129 Instruction *TheCall = CS.getInstruction();
130130 if (!TheCall) return false; // Not a direct call site?
131
131
132132 // The addr of this function is passed to the call.
133133 if (I.getOperandNo() != 0) return false;
134134 }
135
135
136136 // Okay, we know we can transform this function if safe. Scan its body
137137 // looking for calls to llvm.vastart.
138138 for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
143143 }
144144 }
145145 }
146
146
147147 // If we get here, there are no calls to llvm.vastart in the function body,
148148 // remove the "..." and adjust all the calls.
149
149
150150 // Start by computing a new prototype for the function, which is the same as
151151 // the old function, but has fewer arguments.
152152 const FunctionType *FTy = Fn.getFunctionType();
153153 std::vector Params(FTy->param_begin(), FTy->param_end());
154154 FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false);
155155 unsigned NumArgs = Params.size();
156
156
157157 // Create the new function body and insert it into the module...
158158 Function *NF = new Function(NFTy, Fn.getLinkage());
159159 NF->setCallingConv(Fn.getCallingConv());
160160 NF->setParamAttrs(Fn.getParamAttrs());
161161 Fn.getParent()->getFunctionList().insert(&Fn, NF);
162162 NF->takeName(&Fn);
163
163
164164 // Loop over all of the callers of the function, transforming the call sites
165165 // to pass in a smaller number of arguments into the new function.
166166 //
168168 while (!Fn.use_empty()) {
169169 CallSite CS = CallSite::get(Fn.use_back());
170170 Instruction *Call = CS.getInstruction();
171
171
172172 // Pass all the same arguments.
173173 Args.assign(CS.arg_begin(), CS.arg_begin()+NumArgs);
174
174
175175 Instruction *New;
176176 if (InvokeInst *II = dyn_cast(Call)) {
177177 New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
178178 Args.begin(), Args.end(), "", Call);
179179 cast(New)->setCallingConv(CS.getCallingConv());
180 cast(New)->setParamAttrs(NF->getParamAttrs());
180 cast(New)->setParamAttrs(CS.getParamAttrs());
181181 } else {
182182 New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
183183 cast(New)->setCallingConv(CS.getCallingConv());
184 cast(New)->setParamAttrs(NF->getParamAttrs());
184 cast(New)->setParamAttrs(CS.getParamAttrs());
185185 if (cast(Call)->isTailCall())
186186 cast(New)->setTailCall();
187187 }
188188 Args.clear();
189
189
190190 if (!Call->use_empty())
191191 Call->replaceAllUsesWith(New);
192
192
193193 New->takeName(Call);
194
194
195195 // Finally, remove the old call from the program, reducing the use-count of
196196 // F.
197197 Call->eraseFromParent();
198198 }
199
199
200200 // Since we have now created the new function, splice the body of the old
201201 // function right into the new function, leaving the old rotting hulk of the
202202 // function empty.
203203 NF->getBasicBlockList().splice(NF->begin(), Fn.getBasicBlockList());
204
204
205205 // Loop over the argument list, transfering uses of the old arguments over to
206206 // the new arguments, also transfering over the names as well. While we're at
207207 // it, remove the dead arguments from the DeadArguments list.
212212 I->replaceAllUsesWith(I2);
213213 I2->takeName(I);
214214 }
215
215
216216 // Finally, nuke the old function.
217217 Fn.eraseFromParent();
218218 return true;
495495 ParamAttrsVector ParamAttrsVec;
496496 const ParamAttrsList *PAL = F->getParamAttrs();
497497
498 // The existing function return attributes.
499 uint16_t RAttrs = PAL ? PAL->getParamAttrs(0) : 0;
500
501 // Make the function return void if the return value is dead.
502 const Type *RetTy = FTy->getReturnType();
503 if (DeadRetVal.count(F)) {
504 RetTy = Type::VoidTy;
505 RAttrs &= ~ParamAttr::VoidTypeIncompatible;
506 DeadRetVal.erase(F);
507 }
508
509 if (RAttrs)
510 ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, RAttrs));
511
498512 // Construct the new parameter list from non-dead arguments. Also construct
499513 // a new set of parameter attributes to correspond.
500514 unsigned index = 1;
502516 ++I, ++index)
503517 if (!DeadArguments.count(I)) {
504518 Params.push_back(I->getType());
505 if (PAL) {
506 uint16_t Attrs = PAL->getParamAttrs(index);
507 if (Attrs != ParamAttr::None)
508 ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(),
509 Attrs));
510 }
519 uint16_t Attrs = PAL ? PAL->getParamAttrs(index) : 0;
520 if (Attrs)
521 ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(), Attrs));
511522 }
512523
513524 // Reconstruct the ParamAttrsList based on the vector we constructed.
514 if (ParamAttrsVec.empty())
515 PAL = 0;
516 else
517 PAL = ParamAttrsList::get(ParamAttrsVec);
518
519 // Make the function return void if the return value is dead.
520 const Type *RetTy = FTy->getReturnType();
521 if (DeadRetVal.count(F)) {
522 RetTy = Type::VoidTy;
523 DeadRetVal.erase(F);
524 }
525 PAL = ParamAttrsList::get(ParamAttrsVec);
525526
526527 // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
527528 // have zero fixed arguments.
549550 while (!F->use_empty()) {
550551 CallSite CS = CallSite::get(F->use_back());
551552 Instruction *Call = CS.getInstruction();
553 ParamAttrsVec.clear();
554 PAL = CS.getParamAttrs();
555
556 // The call return attributes.
557 uint16_t RAttrs = PAL ? PAL->getParamAttrs(0) : 0;
558 // Adjust in case the function was changed to return void.
559 if (NF->getReturnType() == Type::VoidTy)
560 RAttrs &= ~ParamAttr::VoidTypeIncompatible;
561 if (RAttrs)
562 ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, RAttrs));
552563
553564 // Loop over the operands, deleting dead ones...
554565 CallSite::arg_iterator AI = CS.arg_begin();
566 index = 1;
555567 for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
556 I != E; ++I, ++AI)
557 if (!DeadArguments.count(I)) // Remove operands for dead arguments
568 I != E; ++I, ++AI, ++index)
569 if (!DeadArguments.count(I)) { // Remove operands for dead arguments
558570 Args.push_back(*AI);
571 uint16_t Attrs = PAL ? PAL->getParamAttrs(index) : 0;
572 if (Attrs)
573 ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs));
574 }
575
576 // Reconstruct the ParamAttrsList based on the vector we constructed.
577 PAL = ParamAttrsList::get(ParamAttrsVec);
559578
560579 if (ExtraArgHack)
561580 Args.push_back(UndefValue::get(Type::Int32Ty));
0 ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | grep nounwind | count 2
1 ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | grep signext | count 2
2 ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | not grep inreg
3 ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | not grep zeroext
4
5 @g = global i8 0
6
7 define internal i8 @foo(i8* inreg %p, i8 signext %y, ... ) zeroext nounwind {
8 store i8 %y, i8* @g
9 ret i8 0
10 }
11
12 define i32 @bar() {
13 %A = call i8(i8*, i8, ...)* @foo(i8* inreg null, i8 signext 1, i8 2) zeroext nounwind
14 ret i32 0
15 }