r324377 - Pass around function pointers as CGCallees, not bare llvm::Value*s.
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 6 10:52:44 PST 2018
Author: rjmccall
Date: Tue Feb 6 10:52:44 2018
New Revision: 324377
URL: http://llvm.org/viewvc/llvm-project?rev=324377&view=rev
Log:
Pass around function pointers as CGCallees, not bare llvm::Value*s.
The intention here is to make it easy to write frontend-assisted CFI
systems by propagating extra information in the CGCallee.
Modified:
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/CodeGen/CGCall.h
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=324377&r1=324376&r2=324377&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Feb 6 10:52:44 2018
@@ -413,10 +413,10 @@ public:
CharUnits VPtrOffset) = 0;
/// Build a virtual function pointer in the ABI-specific way.
- virtual llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD, Address This,
- llvm::Type *Ty,
- SourceLocation Loc) = 0;
+ virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF,
+ GlobalDecl GD, Address This,
+ llvm::Type *Ty,
+ SourceLocation Loc) = 0;
/// Emit the ABI-specific virtual destructor call.
virtual llvm::Value *
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=324377&r1=324376&r2=324377&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Feb 6 10:52:44 2018
@@ -4052,14 +4052,8 @@ RValue CodeGenFunction::EmitCall(const C
}
}
- llvm::Value *CalleePtr;
- if (Callee.isVirtual()) {
- const CallExpr *CE = Callee.getVirtualCallExpr();
- CalleePtr = CGM.getCXXABI().getVirtualFunctionPointer(
- *this, Callee.getVirtualMethodDecl(), Callee.getThisAddress(),
- Callee.getFunctionType(), CE ? CE->getLocStart() : SourceLocation());
- } else
- CalleePtr = Callee.getFunctionPointer();
+ const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*this);
+ llvm::Value *CalleePtr = ConcreteCallee.getFunctionPointer();
// If we're using inalloca, set up that argument.
if (ArgMemory.isValid()) {
@@ -4412,6 +4406,17 @@ RValue CodeGenFunction::EmitCall(const C
return Ret;
}
+CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
+ if (isVirtual()) {
+ const CallExpr *CE = getVirtualCallExpr();
+ return CGF.CGM.getCXXABI().getVirtualFunctionPointer(
+ CGF, getVirtualMethodDecl(), getThisAddress(),
+ getFunctionType(), CE ? CE->getLocStart() : SourceLocation());
+ }
+
+ return *this;
+}
+
/* VarArg handling */
Address CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) {
Modified: cfe/trunk/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=324377&r1=324376&r2=324377&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.h (original)
+++ cfe/trunk/lib/CodeGen/CGCall.h Tue Feb 6 10:52:44 2018
@@ -206,6 +206,10 @@ public:
return cast<llvm::FunctionType>(
getFunctionPointer()->getType()->getPointerElementType());
}
+
+ /// If this is a delayed callee computation of some sort, prepare
+ /// a concrete callee.
+ CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const;
};
struct CallArg {
Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=324377&r1=324376&r2=324377&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Feb 6 10:52:44 2018
@@ -280,9 +280,9 @@ public:
llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
CharUnits VPtrOffset) override;
- llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
- Address This, llvm::Type *Ty,
- SourceLocation Loc) override;
+ CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
+ Address This, llvm::Type *Ty,
+ SourceLocation Loc) override;
llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
@@ -1651,42 +1651,47 @@ llvm::GlobalVariable *ItaniumCXXABI::get
return VTable;
}
-llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD,
- Address This,
- llvm::Type *Ty,
- SourceLocation Loc) {
+CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
+ GlobalDecl GD,
+ Address This,
+ llvm::Type *Ty,
+ SourceLocation Loc) {
GD = GD.getCanonicalDecl();
Ty = Ty->getPointerTo()->getPointerTo();
auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
llvm::Value *VTable = CGF.GetVTablePtr(This, Ty, MethodDecl->getParent());
uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
- if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent()))
- return CGF.EmitVTableTypeCheckedLoad(
+ llvm::Value *VFunc;
+ if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
+ VFunc = CGF.EmitVTableTypeCheckedLoad(
MethodDecl->getParent(), VTable,
VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
+ } else {
+ CGF.EmitTypeMetadataCodeForVCall(MethodDecl->getParent(), VTable, Loc);
- CGF.EmitTypeMetadataCodeForVCall(MethodDecl->getParent(), VTable, Loc);
+ llvm::Value *VFuncPtr =
+ CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
+ auto *VFuncLoad =
+ CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
+
+ // Add !invariant.load md to virtual function load to indicate that
+ // function didn't change inside vtable.
+ // It's safe to add it without -fstrict-vtable-pointers, but it would not
+ // help in devirtualization because it will only matter if we will have 2
+ // the same virtual function loads from the same vtable load, which won't
+ // happen without enabled devirtualization with -fstrict-vtable-pointers.
+ if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
+ CGM.getCodeGenOpts().StrictVTablePointers)
+ VFuncLoad->setMetadata(
+ llvm::LLVMContext::MD_invariant_load,
+ llvm::MDNode::get(CGM.getLLVMContext(),
+ llvm::ArrayRef<llvm::Metadata *>()));
+ VFunc = VFuncLoad;
+ }
- llvm::Value *VFuncPtr =
- CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
- auto *VFuncLoad =
- CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
-
- // Add !invariant.load md to virtual function load to indicate that
- // function didn't change inside vtable.
- // It's safe to add it without -fstrict-vtable-pointers, but it would not
- // help in devirtualization because it will only matter if we will have 2
- // the same virtual function loads from the same vtable load, which won't
- // happen without enabled devirtualization with -fstrict-vtable-pointers.
- if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
- CGM.getCodeGenOpts().StrictVTablePointers)
- VFuncLoad->setMetadata(
- llvm::LLVMContext::MD_invariant_load,
- llvm::MDNode::get(CGM.getLLVMContext(),
- llvm::ArrayRef<llvm::Metadata *>()));
- return VFuncLoad;
+ CGCallee Callee(MethodDecl, VFunc);
+ return Callee;
}
llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=324377&r1=324376&r2=324377&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Feb 6 10:52:44 2018
@@ -285,9 +285,9 @@ public:
llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
CharUnits VPtrOffset) override;
- llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
- Address This, llvm::Type *Ty,
- SourceLocation Loc) override;
+ CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
+ Address This, llvm::Type *Ty,
+ SourceLocation Loc) override;
llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
@@ -1827,11 +1827,11 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
return VTable;
}
-llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD,
- Address This,
- llvm::Type *Ty,
- SourceLocation Loc) {
+CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
+ GlobalDecl GD,
+ Address This,
+ llvm::Type *Ty,
+ SourceLocation Loc) {
GD = GD.getCanonicalDecl();
CGBuilderTy &Builder = CGF.Builder;
@@ -1858,17 +1858,22 @@ llvm::Value *MicrosoftCXXABI::getVirtual
->ObjectWithVPtr;
};
- if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent()))
- return CGF.EmitVTableTypeCheckedLoad(
+ llvm::Value *VFunc;
+ if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
+ VFunc = CGF.EmitVTableTypeCheckedLoad(
getObjectWithVPtr(), VTable,
ML.Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
+ } else {
+ if (CGM.getCodeGenOpts().PrepareForLTO)
+ CGF.EmitTypeMetadataCodeForVCall(getObjectWithVPtr(), VTable, Loc);
- if (CGM.getCodeGenOpts().PrepareForLTO)
- CGF.EmitTypeMetadataCodeForVCall(getObjectWithVPtr(), VTable, Loc);
+ llvm::Value *VFuncPtr =
+ Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
+ VFunc = Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
+ }
- llvm::Value *VFuncPtr =
- Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
- return Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
+ CGCallee Callee(MethodDecl, VFunc);
+ return Callee;
}
llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
More information about the cfe-commits
mailing list