summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2019-02-07 01:15:41 +0000
committerJames Y Knight <jyknight@google.com>2019-02-07 01:15:41 +0000
commitcfe8cd7e06aab1ff4852e4da829aa0e2e1f94214 (patch)
treebd849d36968a420705e5674b2431ba8b524dd9fd
parentf7321540d518b2a428ac78ba34900cd437626246 (diff)
downloadbcm5719-llvm-cfe8cd7e06aab1ff4852e4da829aa0e2e1f94214.tar.gz
bcm5719-llvm-cfe8cd7e06aab1ff4852e4da829aa0e2e1f94214.zip
[opaque pointer types] Make EmitCall pass Function Types to
CreateCall/Invoke. Also, remove the getFunctionType() function from CGCallee, since it accesses the pointee type of the value. The only use was in EmitCall, so just inline it into the debug assertion. This is the last of the changes for Call and Invoke in clang. Differential Revision: https://reviews.llvm.org/D57804 llvm-svn: 353356
-rw-r--r--clang/lib/CodeGen/CGCall.cpp50
-rw-r--r--clang/lib/CodeGen/CGCall.h9
2 files changed, 33 insertions, 26 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 42eaf741346..b119c46954c 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3826,7 +3826,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
QualType RetTy = CallInfo.getReturnType();
const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
- llvm::FunctionType *IRFuncTy = Callee.getFunctionType();
+ llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo);
#ifndef NDEBUG
if (!(CallInfo.isVariadic() && CallInfo.getArgStruct())) {
@@ -3837,8 +3837,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
//
// In other cases, we assert that the types match up (until pointers stop
// having pointee types).
- llvm::FunctionType *IRFuncTyFromInfo = getTypes().GetFunctionType(CallInfo);
- assert(IRFuncTy == IRFuncTyFromInfo);
+ llvm::Type *TypeFromVal;
+ if (Callee.isVirtual())
+ TypeFromVal = Callee.getVirtualFunctionType();
+ else
+ TypeFromVal =
+ Callee.getFunctionPointer()->getType()->getPointerElementType();
+ assert(IRFuncTy == TypeFromVal);
}
#endif
@@ -4207,8 +4212,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// cases, we can't do any parameter mismatch checks. Give up and bitcast
// the callee.
unsigned CalleeAS = CalleePtr->getType()->getPointerAddressSpace();
- auto FnTy = getTypes().GetFunctionType(CallInfo)->getPointerTo(CalleeAS);
- CalleePtr = Builder.CreateBitCast(CalleePtr, FnTy);
+ CalleePtr =
+ Builder.CreateBitCast(CalleePtr, IRFuncTy->getPointerTo(CalleeAS));
} else {
llvm::Type *LastParamTy =
IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1);
@@ -4240,19 +4245,20 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
//
// This makes the IR nicer, but more importantly it ensures that we
// can inline the function at -O0 if it is marked always_inline.
- auto simplifyVariadicCallee = [](llvm::Value *Ptr) -> llvm::Value* {
- llvm::FunctionType *CalleeFT =
- cast<llvm::FunctionType>(Ptr->getType()->getPointerElementType());
+ auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
+ llvm::Value *Ptr) -> llvm::Function * {
if (!CalleeFT->isVarArg())
- return Ptr;
+ return nullptr;
- llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr);
- if (!CE || CE->getOpcode() != llvm::Instruction::BitCast)
- return Ptr;
+ // Get underlying value if it's a bitcast
+ if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
+ if (CE->getOpcode() == llvm::Instruction::BitCast)
+ Ptr = CE->getOperand(0);
+ }
- llvm::Function *OrigFn = dyn_cast<llvm::Function>(CE->getOperand(0));
+ llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
if (!OrigFn)
- return Ptr;
+ return nullptr;
llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
@@ -4261,15 +4267,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (OrigFT->isVarArg() ||
OrigFT->getNumParams() != CalleeFT->getNumParams() ||
OrigFT->getReturnType() != CalleeFT->getReturnType())
- return Ptr;
+ return nullptr;
for (unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
- return Ptr;
+ return nullptr;
return OrigFn;
};
- CalleePtr = simplifyVariadicCallee(CalleePtr);
+
+ if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
+ CalleePtr = OrigFn;
+ IRFuncTy = OrigFn->getFunctionType();
+ }
// 3. Perform the actual call.
@@ -4364,10 +4374,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Emit the actual call/invoke instruction.
llvm::CallBase *CI;
if (!InvokeDest) {
- CI = Builder.CreateCall(CalleePtr, IRCallArgs, BundleList);
+ CI = Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
} else {
llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
- CI = Builder.CreateInvoke(CalleePtr, Cont, InvokeDest, IRCallArgs,
+ CI = Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
BundleList);
EmitBlock(Cont);
}
@@ -4591,7 +4601,7 @@ CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
if (isVirtual()) {
const CallExpr *CE = getVirtualCallExpr();
return CGF.CGM.getCXXABI().getVirtualFunctionPointer(
- CGF, getVirtualMethodDecl(), getThisAddress(), getFunctionType(),
+ CGF, getVirtualMethodDecl(), getThisAddress(), getVirtualFunctionType(),
CE ? CE->getBeginLoc() : SourceLocation());
}
diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h
index 27c1bcae7e6..cc11ded704a 100644
--- a/clang/lib/CodeGen/CGCall.h
+++ b/clang/lib/CodeGen/CGCall.h
@@ -204,12 +204,9 @@ public:
assert(isVirtual());
return VirtualInfo.Addr;
}
-
- llvm::FunctionType *getFunctionType() const {
- if (isVirtual())
- return VirtualInfo.FTy;
- return cast<llvm::FunctionType>(
- getFunctionPointer()->getType()->getPointerElementType());
+ llvm::FunctionType *getVirtualFunctionType() const {
+ assert(isVirtual());
+ return VirtualInfo.FTy;
}
/// If this is a delayed callee computation of some sort, prepare
OpenPOWER on IntegriCloud