From: James Y Knight Date: Fri, 1 Feb 2019 20:44:54 +0000 (+0000) Subject: [opaque pointer types] Pass function type for CallBase::setCalledFunction. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3641e513697ded5b996102e6f31c51d62a7362c0;p=llvm [opaque pointer types] Pass function type for CallBase::setCalledFunction. Differential Revision: https://reviews.llvm.org/D57174 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352914 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index d11b6b01b1f..6d27005e881 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -121,9 +121,13 @@ public: return true; } - /// Set the callee to the specified value. + /// Set the callee to the specified value. Unlike the function of the same + /// name on CallBase, does not modify the type! void setCalledFunction(Value *V) { assert(getInstruction() && "Not a call or invoke instruction!"); + assert(cast(V->getType())->getElementType() == + cast(getInstruction())->getFunctionType() && + "New callee type does not match FunctionType on call"); *getCallee() = V; } diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 71dd9ece506..351b79a09e6 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -27,6 +27,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/OperandTraits.h" @@ -1226,10 +1227,8 @@ public: void setCalledOperand(Value *V) { Op() = V; } /// Sets the function called, including updating the function type. - void setCalledFunction(Value *Fn) { - setCalledFunction( - cast(cast(Fn->getType())->getElementType()), - Fn); + void setCalledFunction(Function *Fn) { + setCalledFunction(Fn->getFunctionType(), Fn); } /// Sets the function called, including updating the function type. @@ -1243,6 +1242,9 @@ public: this->FTy = FTy; assert(FTy == cast( cast(Fn->getType())->getElementType())); + // This function doesn't mutate the return type, only the function + // type. Seems broken, but I'm just gonna stick an assert in for now. + assert(getType() == FTy->getReturnType()); setCalledOperand(Fn); } diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 80eb51be84e..b34b3fd1619 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -4214,7 +4214,8 @@ Instruction *InstCombiner::visitCallBase(CallBase &Call) { // We cannot remove an invoke, because it would change the CFG, just // change the callee to a null pointer. cast(OldCall)->setCalledFunction( - Constant::getNullValue(CalleeF->getType())); + CalleeF->getFunctionType(), + Constant::getNullValue(CalleeF->getType())); return nullptr; } } @@ -4555,8 +4556,8 @@ Instruction * InstCombiner::transformCallThroughTrampoline(CallBase &Call, IntrinsicInst &Tramp) { Value *Callee = Call.getCalledValue(); - PointerType *PTy = cast(Callee->getType()); - FunctionType *FTy = cast(PTy->getElementType()); + Type *CalleeTy = Callee->getType(); + FunctionType *FTy = Call.getFunctionType(); AttributeList Attrs = Call.getAttributes(); // If the call already has the 'nest' attribute somewhere then give up - @@ -4565,7 +4566,7 @@ InstCombiner::transformCallThroughTrampoline(CallBase &Call, return nullptr; Function *NestF = cast(Tramp.getArgOperand(1)->stripPointerCasts()); - FunctionType *NestFTy = cast(NestF->getValueType()); + FunctionType *NestFTy = NestF->getFunctionType(); AttributeList NestAttrs = NestF->getAttributes(); if (!NestAttrs.isEmpty()) { @@ -4689,9 +4690,7 @@ InstCombiner::transformCallThroughTrampoline(CallBase &Call, // Replace the trampoline call with a direct call. Since there is no 'nest' // parameter, there is no need to adjust the argument list. Let the generic // code sort out any function type mismatches. - Constant *NewCallee = - NestF->getType() == PTy ? NestF : - ConstantExpr::getBitCast(NestF, PTy); - Call.setCalledFunction(NewCallee); + Constant *NewCallee = ConstantExpr::getBitCast(NestF, CalleeTy); + Call.setCalledFunction(FTy, NewCallee); return &Call; } diff --git a/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/lib/Transforms/ObjCARC/ObjCARCContract.cpp index a424f5323b9..6613f6a76d0 100644 --- a/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -139,7 +139,7 @@ bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) { // We do not have to worry about tail calls/does not throw since // retain/retainRV have the same properties. - Constant *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV); + Function *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV); cast(Retain)->setCalledFunction(Decl); LLVM_DEBUG(dbgs() << "New: " << *Retain << "\n"); @@ -188,7 +188,7 @@ bool ObjCARCContract::contractAutorelease( " Retain: " << *Retain << "\n"); - Constant *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV + Function *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV : ARCRuntimeEntryPointKind::RetainAutorelease); Retain->setCalledFunction(Decl); diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index bfec15ca9c7..9572674f758 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -641,7 +641,7 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) { "Old = " << *RetainRV << "\n"); - Constant *NewDecl = EP.get(ARCRuntimeEntryPointKind::Retain); + Function *NewDecl = EP.get(ARCRuntimeEntryPointKind::Retain); cast(RetainRV)->setCalledFunction(NewDecl); LLVM_DEBUG(dbgs() << "New = " << *RetainRV << "\n"); @@ -690,7 +690,7 @@ void ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F, << *AutoreleaseRV << "\n"); CallInst *AutoreleaseRVCI = cast(AutoreleaseRV); - Constant *NewDecl = EP.get(ARCRuntimeEntryPointKind::Autorelease); + Function *NewDecl = EP.get(ARCRuntimeEntryPointKind::Autorelease); AutoreleaseRVCI->setCalledFunction(NewDecl); AutoreleaseRVCI->setTailCall(false); // Never tail call objc_autorelease. Class = ARCInstKind::Autorelease; diff --git a/lib/Transforms/Utils/CallPromotionUtils.cpp b/lib/Transforms/Utils/CallPromotionUtils.cpp index 681c5a7de93..1cb883517e8 100644 --- a/lib/Transforms/Utils/CallPromotionUtils.cpp +++ b/lib/Transforms/Utils/CallPromotionUtils.cpp @@ -366,8 +366,9 @@ Instruction *llvm::promoteCall(CallSite CS, Function *Callee, CastInst **RetBitCast) { assert(!CS.getCalledFunction() && "Only indirect call sites can be promoted"); - // Set the called function of the call site to be the given callee. - CS.setCalledFunction(Callee); + // Set the called function of the call site to be the given callee (but don't + // change the type). + cast(CS.getInstruction())->setCalledOperand(Callee); // Since the call site will no longer be direct, we must clear metadata that // is only appropriate for indirect calls. This includes !prof and !callees