llvm.org GIT mirror llvm / ad9a9e1
The transform that tries to turn calls to bitcast functions into direct calls bails out unless caller and callee have essentially equivalent parameter attributes. This is illogical - the callee's attributes should be of no relevance here. Rework the logic, which incidentally fixes a crash when removed arguments have attributes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45658 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 11 years ago
6 changed file(s) with 97 addition(s) and 90 deletion(s). Raw diff Collapse all Expand all
2121 #include
2222
2323 namespace llvm {
24 class Type;
25
2426 namespace ParamAttr {
2527
2628 /// Function parameters and results can have attributes to indicate how they
4345 ReadOnly = 1 << 10 ///< Function only reads from memory
4446 };
4547
46 /// These attributes can safely be dropped from a function or a function call:
47 /// doing so may reduce the number of optimizations performed, but it will not
48 /// change a correct program into an incorrect one.
49 /// @brief Attributes that do not change the calling convention.
50 const uint16_t Informative = NoReturn | NoUnwind | NoAlias |
51 ReadNone | ReadOnly;
52
5348 /// @brief Attributes that only apply to function parameters.
5449 const uint16_t ParameterOnly = ByVal | InReg | Nest | StructRet;
5550
6156
6257 /// @brief Attributes that only apply to pointers.
6358 const uint16_t PointerTypeOnly = ByVal | Nest | NoAlias | StructRet;
64
65 /// @brief Attributes that do not apply to void type function return values.
66 const uint16_t VoidTypeIncompatible = IntegerTypeOnly | PointerTypeOnly |
67 ParameterOnly;
6859
6960 /// @brief Attributes that are mutually incompatible.
7061 const uint16_t MutuallyIncompatible[3] = {
7263 ZExt | SExt,
7364 ReadNone | ReadOnly
7465 };
66
67 /// @brief Which of the given attributes do not apply to the type.
68 uint16_t incompatibleWithType (const Type *Ty, uint16_t attrs);
7569
7670 } // end namespace ParamAttr
7771
157151 static const ParamAttrsList *excludeAttrs(const ParamAttrsList *PAL,
158152 uint16_t idx, uint16_t attrs);
159153
160 /// Returns whether each of the specified lists of attributes can be safely
161 /// replaced with the other in a function or a function call.
162 /// @brief Whether one attribute list can safely replace the other.
163 static bool areCompatible(const ParamAttrsList *A, const ParamAttrsList *B);
164
165154 /// @}
166155 /// @name Accessors
167156 /// @{
504504 const Type *RetTy = FTy->getReturnType();
505505 if (DeadRetVal.count(F)) {
506506 RetTy = Type::VoidTy;
507 RAttrs &= ~ParamAttr::VoidTypeIncompatible;
507 RAttrs &= ~ParamAttr::incompatibleWithType(RetTy, RAttrs);
508508 DeadRetVal.erase(F);
509509 }
510510
560560 // The call return attributes.
561561 uint16_t RAttrs = PAL ? PAL->getParamAttrs(0) : 0;
562562 // Adjust in case the function was changed to return void.
563 if (NF->getReturnType() == Type::VoidTy)
564 RAttrs &= ~ParamAttr::VoidTypeIncompatible;
563 RAttrs &= ~ParamAttr::incompatibleWithType(NF->getReturnType(), RAttrs);
565564 if (RAttrs)
566565 ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, RAttrs));
567566
80738073 return false;
80748074 Function *Callee = cast(CE->getOperand(0));
80758075 Instruction *Caller = CS.getInstruction();
8076 const ParamAttrsList* CallerPAL = CS.getParamAttrs();
80768077
80778078 // Okay, this is a cast from a function to a different type. Unless doing so
80788079 // would cause a type conversion of one of our arguments, change this call to
80808081 //
80818082 const FunctionType *FT = Callee->getFunctionType();
80828083 const Type *OldRetTy = Caller->getType();
8083
8084 const ParamAttrsList* CallerPAL = CS.getParamAttrs();
8085
8086 // If the parameter attributes are not compatible, don't do the xform. We
8087 // don't want to lose an sret attribute or something.
8088 if (!ParamAttrsList::areCompatible(CallerPAL, Callee->getParamAttrs()))
8089 return false;
80908084
80918085 // Check to see if we are changing the return type...
80928086 if (OldRetTy != FT->getReturnType()) {
81018095 // void -> non-void is handled specially
81028096 FT->getReturnType() != Type::VoidTy)
81038097 return false; // Cannot transform this return value.
8098
8099 if (!Caller->use_empty() && CallerPAL &&
8100 ParamAttr::incompatibleWithType(FT->getReturnType(),
8101 CallerPAL->getParamAttrs(0)))
8102 return false; // Attribute not compatible with transformed value.
81048103
81058104 // If the callsite is an invoke instruction, and the return value is used by
81068105 // a PHI node in a successor, we cannot change the return type of the call
81258124 const Type *ActTy = (*AI)->getType();
81268125
81278126 if (!CastInst::isCastable(ActTy, ParamTy))
8128 return false;
8127 return false; // Cannot transform this parameter value.
8128
8129 if (CallerPAL &&
8130 ParamAttr::incompatibleWithType(ParamTy, CallerPAL->getParamAttrs(i+1)))
8131 return false; // Attribute not compatible with transformed value.
81298132
81308133 ConstantInt *c = dyn_cast(*AI);
81318134 // Some conversions are safe even if we do not have a body.
81438146 Callee->isDeclaration())
81448147 return false; // Do not delete arguments unless we have a function body...
81458148
8149 if (FT->getNumParams() < NumActualArgs && FT->isVarArg())
8150 // In this case we have more arguments than the new function type, but we
8151 // won't be dropping them. Some of them may have attributes. If so, we
8152 // cannot perform the transform because attributes are not allowed after
8153 // the end of the function type.
8154 if (CallerPAL && CallerPAL->size() &&
8155 CallerPAL->getParamIndex(CallerPAL->size()-1) > FT->getNumParams())
8156 return false;
8157
81468158 // Okay, we decided that this is a safe thing to do: go ahead and start
81478159 // inserting cast instructions as necessary...
81488160 std::vector Args;
81498161 Args.reserve(NumActualArgs);
8162 ParamAttrsVector attrVec;
8163 attrVec.reserve(NumCommonArgs);
8164
8165 // Get any return attributes.
8166 uint16_t RAttrs = CallerPAL ? CallerPAL->getParamAttrs(0) : 0;
8167
8168 // If the return value is not being used, the type may not be compatible
8169 // with the existing attributes. Wipe out any problematic attributes.
8170 RAttrs &= ~ParamAttr::incompatibleWithType(FT->getReturnType(), RAttrs);
8171
8172 // Add the new return attributes.
8173 if (RAttrs)
8174 attrVec.push_back(ParamAttrsWithIndex::get(0, RAttrs));
81508175
81518176 AI = CS.arg_begin();
81528177 for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
81598184 CastInst *NewCast = CastInst::create(opcode, *AI, ParamTy, "tmp");
81608185 Args.push_back(InsertNewInstBefore(NewCast, *Caller));
81618186 }
8187
8188 // Add any parameter attributes.
8189 uint16_t PAttrs = CallerPAL ? CallerPAL->getParamAttrs(i + 1) : 0;
8190 if (PAttrs)
8191 attrVec.push_back(ParamAttrsWithIndex::get(i + 1, PAttrs));
81628192 }
81638193
81648194 // If the function takes more arguments than the call was taking, add them
81868216 Args.push_back(*AI);
81878217 }
81888218 }
8219
8220 // No need to add parameter attributes - we already checked that there
8221 // aren't any.
81898222 }
81908223
81918224 if (FT->getReturnType() == Type::VoidTy)
81928225 Caller->setName(""); // Void type should not have a name.
8226
8227 const ParamAttrsList* NewCallerPAL = ParamAttrsList::get(attrVec);
81938228
81948229 Instruction *NC;
81958230 if (InvokeInst *II = dyn_cast(Caller)) {
81968231 NC = new InvokeInst(Callee, II->getNormalDest(), II->getUnwindDest(),
81978232 Args.begin(), Args.end(), Caller->getName(), Caller);
81988233 cast(NC)->setCallingConv(II->getCallingConv());
8199 cast(NC)->setParamAttrs(CallerPAL);
8234 cast(NC)->setParamAttrs(NewCallerPAL);
82008235 } else {
82018236 NC = new CallInst(Callee, Args.begin(), Args.end(),
82028237 Caller->getName(), Caller);
82048239 if (CI->isTailCall())
82058240 cast(NC)->setTailCall();
82068241 cast(NC)->setCallingConv(CI->getCallingConv());
8207 cast(NC)->setParamAttrs(CallerPAL);
8242 cast(NC)->setParamAttrs(NewCallerPAL);
82088243 }
82098244
82108245 // Insert a cast of the return type as necessary.
66 //
77 //===----------------------------------------------------------------------===//
88 //
9 // This file implements the ParamAttrsList class.
9 // This file implements the ParamAttrsList class and ParamAttr utilities.
1010 //
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "llvm/ParameterAttributes.h"
14 #include "llvm/DerivedTypes.h"
1415 #include "llvm/Support/ManagedStatic.h"
1516
1617 using namespace llvm;
6263 return Result;
6364 }
6465
65 /// onlyInformative - Returns whether only informative attributes are set.
66 static inline bool onlyInformative(uint16_t attrs) {
67 return !(attrs & ~ParamAttr::Informative);
68 }
69
70 bool
71 ParamAttrsList::areCompatible(const ParamAttrsList *A, const ParamAttrsList *B){
72 if (A == B)
73 return true;
74 unsigned ASize = A ? A->size() : 0;
75 unsigned BSize = B ? B->size() : 0;
76 unsigned AIndex = 0;
77 unsigned BIndex = 0;
78
79 while (AIndex < ASize && BIndex < BSize) {
80 uint16_t AIdx = A->getParamIndex(AIndex);
81 uint16_t BIdx = B->getParamIndex(BIndex);
82 uint16_t AAttrs = A->getParamAttrsAtIndex(AIndex);
83 uint16_t BAttrs = B->getParamAttrsAtIndex(AIndex);
84
85 if (AIdx < BIdx) {
86 if (!onlyInformative(AAttrs))
87 return false;
88 ++AIndex;
89 } else if (BIdx < AIdx) {
90 if (!onlyInformative(BAttrs))
91 return false;
92 ++BIndex;
93 } else {
94 if (!onlyInformative(AAttrs ^ BAttrs))
95 return false;
96 ++AIndex;
97 ++BIndex;
98 }
99 }
100 for (; AIndex < ASize; ++AIndex)
101 if (!onlyInformative(A->getParamAttrsAtIndex(AIndex)))
102 return false;
103 for (; BIndex < BSize; ++BIndex)
104 if (!onlyInformative(B->getParamAttrsAtIndex(AIndex)))
105 return false;
106 return true;
107 }
108
10966 void ParamAttrsList::Profile(FoldingSetNodeID &ID,
11067 const ParamAttrsVector &Attrs) {
11168 for (unsigned i = 0; i < Attrs.size(); ++i)
228185 return getModified(PAL, modVec);
229186 }
230187
188 uint16_t ParamAttr::incompatibleWithType (const Type *Ty, uint16_t attrs) {
189 uint16_t Incompatible = None;
190
191 if (!Ty->isInteger())
192 Incompatible |= IntegerTypeOnly;
193
194 if (!isa(Ty))
195 Incompatible |= PointerTypeOnly;
196 else if (attrs & ParamAttr::ByVal) {
197 const PointerType *PTy = cast(Ty);
198 if (!isa(PTy->getElementType()))
199 Incompatible |= ParamAttr::ByVal;
200 }
201
202 return attrs & Incompatible;
203 }
417417 Attrs->getParamAttrsText(MutI) + "are incompatible!", V);
418418 }
419419
420 uint16_t IType = Attr & ParamAttr::IntegerTypeOnly;
421 Assert1(!IType || FT->getParamType(Idx-1)->isInteger(),
422 "Attribute " + Attrs->getParamAttrsText(IType) +
423 "should only apply to Integer type!", V);
424
425 uint16_t PType = Attr & ParamAttr::PointerTypeOnly;
426 Assert1(!PType || isa(FT->getParamType(Idx-1)),
427 "Attribute " + Attrs->getParamAttrsText(PType) +
428 "should only apply to Pointer type!", V);
429
430 if (Attr & ParamAttr::ByVal) {
431 const PointerType *Ty =
432 dyn_cast(FT->getParamType(Idx-1));
433 Assert1(!Ty || isa(Ty->getElementType()),
434 "Attribute byval should only apply to pointer to structs!", V);
435 }
420 uint16_t IType = ParamAttr::incompatibleWithType(FT->getParamType(Idx-1),
421 Attr);
422 Assert1(!IType, "Wrong type for attribute " +
423 Attrs->getParamAttrsText(IType), V);
436424
437425 if (Attr & ParamAttr::Nest) {
438426 Assert1(!SawNest, "More than one parameter has attribute nest!", V);
0 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep bitcast | count 2
1
2 define void @a() {
3 ret void
4 }
5
6 define i32 @b(i32* inreg %x) signext {
7 ret i32 0
8 }
9
10 define void @c(...) {
11 ret void
12 }
13
14 define void @g(i32* %y) {
15 call void bitcast (void ()* @a to void (i32*)*)( i32* noalias %y )
16 call <2 x i32> bitcast (i32 (i32*)* @b to <2 x i32> (i32*)*)( i32* inreg null ) ; <<2 x i32>>:1 [#uses=0]
17 %x = call i64 bitcast (i32 (i32*)* @b to i64 (i32)*)( i32 0 ) ; [#uses=0]
18 call void bitcast (void (...)* @c to void (i32)*)( i32 0 )
19 call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)( i32 zeroext 0 ) ; :2 [#uses=0]
20 call void bitcast (void (...)* @c to void (i32)*)( i32 zeroext 0 )
21 ret void
22 }