Skip to content

Commit

Permalink
[NFC] Move storage of dispatch-version to GlobalDecl
Browse files Browse the repository at this point in the history
As suggested by Richard Smith, and initially put up for review here:
https://reviews.llvm.org/D53341, this patch removes a hack that was used
to ensure that proper target-feature lists were used when emitting
cpu-dispatch (and eventually, target-clones) implementations. As a part
of this, the GlobalDecl object is proliferated to a bunch more
locations.

Originally, this was put up for review (see above) to get acceptance on
the approach, though discussion with Richard in San Diego showed he
approved of the approach taken here.  Thus, I believe this is acceptable
for Review-After-commit

Differential Revision: https://reviews.llvm.org/D53341

Change-Id: I0a0bd673340d334d93feac789d653e03d9f6b1d5
llvm-svn: 346757
  • Loading branch information
Erich Keane committed Nov 13, 2018
1 parent 28e2dbb commit de6480a
Show file tree
Hide file tree
Showing 21 changed files with 182 additions and 120 deletions.
28 changes: 26 additions & 2 deletions clang/include/clang/AST/GlobalDecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace clang {
/// a VarDecl, a FunctionDecl or a BlockDecl.
class GlobalDecl {
llvm::PointerIntPair<const Decl *, 2> Value;
unsigned MultiVersionIndex = 0;

void Init(const Decl *D) {
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
Expand All @@ -45,7 +46,10 @@ class GlobalDecl {
public:
GlobalDecl() = default;
GlobalDecl(const VarDecl *D) { Init(D);}
GlobalDecl(const FunctionDecl *D) { Init(D); }
GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
: MultiVersionIndex(MVIndex) {
Init(D);
}
GlobalDecl(const BlockDecl *D) { Init(D); }
GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
Expand All @@ -57,6 +61,7 @@ class GlobalDecl {
GlobalDecl CanonGD;
CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
CanonGD.Value.setInt(Value.getInt());
CanonGD.MultiVersionIndex = MultiVersionIndex;

return CanonGD;
}
Expand All @@ -73,8 +78,17 @@ class GlobalDecl {
return static_cast<CXXDtorType>(Value.getInt());
}

unsigned getMultiVersionIndex() const {
assert(isa<FunctionDecl>(getDecl()) &&
!isa<CXXConstructorDecl>(getDecl()) &&
!isa<CXXDestructorDecl>(getDecl()) &&
"Decl is not a plain FunctionDecl!");
return MultiVersionIndex;
}

friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
return LHS.Value == RHS.Value;
return LHS.Value == RHS.Value &&
LHS.MultiVersionIndex == RHS.MultiVersionIndex;
}

void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
Expand All @@ -90,6 +104,16 @@ class GlobalDecl {
Result.Value.setPointer(D);
return Result;
}

GlobalDecl getWithMultiVersionIndex(unsigned Index) {
assert(isa<FunctionDecl>(getDecl()) &&
!isa<CXXConstructorDecl>(getDecl()) &&
!isa<CXXDestructorDecl>(getDecl()) &&
"Decl is not a plain FunctionDecl!");
GlobalDecl Result(*this);
Result.MultiVersionIndex = Index;
return Result;
}
};

} // namespace clang
Expand Down
6 changes: 2 additions & 4 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -864,10 +864,8 @@ def CPUSpecific : InheritableAttr {
let Subjects = SubjectList<[Function]>;
let Documentation = [CPUSpecificCPUDispatchDocs];
let AdditionalMembers = [{
unsigned ActiveArgIndex = 0;

IdentifierInfo *getCurCPUName() const {
return *(cpus_begin() + ActiveArgIndex);
IdentifierInfo *getCPUName(unsigned Index) const {
return *(cpus_begin() + Index);
}
}];
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGBlocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,7 @@ static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType,
} else {
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
}
}
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {

static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
const CallExpr *E, llvm::Constant *calleeValue) {
CGCallee callee = CGCallee::forDirect(calleeValue, FD);
CGCallee callee = CGCallee::forDirect(calleeValue, GlobalDecl(FD));
return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
}

Expand Down Expand Up @@ -1103,7 +1103,7 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
llvm::Function *Fn = llvm::Function::Create(
FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule());
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);

// Attach 'noinline' at -Oz.
Expand Down Expand Up @@ -1424,9 +1424,10 @@ RValue CodeGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) {
return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt }));
}

RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
unsigned BuiltinID, const CallExpr *E,
RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const CallExpr *E,
ReturnValueSlot ReturnValue) {
const FunctionDecl *FD = GD.getDecl()->getAsFunction();
// See if we can constant fold this builtin. If so, don't emit it at all.
Expr::EvalResult Result;
if (E->EvaluateAsRValue(Result, CGM.getContext()) &&
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
llvm::Value *VFunc =
CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.PointerAlignInBytes);
CGCallee Callee(GD.getDecl()->getCanonicalDecl(), VFunc);
CGCallee Callee(GD, VFunc);
return Callee;
}

Expand Down
15 changes: 9 additions & 6 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1833,7 +1833,7 @@ void CodeGenModule::ConstructAttributeList(
AddAttributesFromFunctionProtoType(getContext(), FuncAttrs,
CalleeInfo.getCalleeFunctionProtoType());

const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl();

bool HasOptnone = false;
// FIXME: handle sseregparm someday...
Expand Down Expand Up @@ -1941,7 +1941,7 @@ void CodeGenModule::ConstructAttributeList(

FuncAttrs.addAttribute("disable-tail-calls",
llvm::toStringRef(DisableTailCalls));
GetCPUAndFeaturesAttributes(TargetDecl, FuncAttrs);
GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
}

ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI);
Expand Down Expand Up @@ -4260,8 +4260,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Apply always_inline to all calls within flatten functions.
// FIXME: should this really take priority over __try, below?
if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
!(Callee.getAbstractInfo().getCalleeDecl() &&
Callee.getAbstractInfo().getCalleeDecl()->hasAttr<NoInlineAttr>())) {
!(Callee.getAbstractInfo().getCalleeDecl().getDecl() &&
Callee.getAbstractInfo()
.getCalleeDecl()
.getDecl()
->hasAttr<NoInlineAttr>())) {
Attrs =
Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex,
llvm::Attribute::AlwaysInline);
Expand Down Expand Up @@ -4346,7 +4349,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,

// Suppress tail calls if requested.
if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl();
const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
}
Expand Down Expand Up @@ -4493,7 +4496,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
} ();

// Emit the assume_aligned check on the return value.
const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl();
const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
if (Ret.isScalar() && TargetDecl) {
if (const auto *AA = TargetDecl->getAttr<AssumeAlignedAttr>()) {
llvm::Value *OffsetValue = nullptr;
Expand Down
14 changes: 7 additions & 7 deletions clang/lib/CodeGen/CGCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ class CGCalleeInfo {
/// The function prototype of the callee.
const FunctionProtoType *CalleeProtoTy;
/// The function declaration of the callee.
const Decl *CalleeDecl;
GlobalDecl CalleeDecl;

public:
explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {}
CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl)
explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl() {}
CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl)
: CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
: CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {}
CGCalleeInfo(const Decl *calleeDecl)
: CalleeProtoTy(calleeProtoTy), CalleeDecl() {}
CGCalleeInfo(GlobalDecl calleeDecl)
: CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}

const FunctionProtoType *getCalleeFunctionProtoType() const {
return CalleeProtoTy;
}
const Decl *getCalleeDecl() const { return CalleeDecl; }
const GlobalDecl getCalleeDecl() const { return CalleeDecl; }
};

/// All available information about a concrete callee.
Expand Down Expand Up @@ -171,7 +171,7 @@ class CGCalleeInfo {
}
CGCalleeInfo getAbstractInfo() const {
if (isVirtual())
return VirtualInfo.MD.getDecl();
return VirtualInfo.MD;
assert(isOrdinary());
return AbstractInfo;
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
CGCallee Callee = CGCallee::forDirect(CalleePtr, D);
CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type));
EmitCall(Info, Callee, ReturnValueSlot(), Args);

// Generate vtable assumptions if we're constructing a complete object
Expand Down Expand Up @@ -2808,7 +2808,7 @@ void CodeGenFunction::EmitForwardingCallToLambda(
// variadic arguments.

// Now emit our call.
auto callee = CGCallee::forDirect(calleePtr, callOperator);
auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator));
RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);

// If necessary, copy the returned value into the slot.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1878,7 +1878,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
CurSEHParent = ParentCGF.CurSEHParent;

CGM.SetLLVMFunctionAttributes(nullptr, FnInfo, CurFn);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FnInfo, CurFn);
EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
}

Expand Down
14 changes: 10 additions & 4 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4375,7 +4375,7 @@ static CGCallee EmitDirectCallee(CodeGenFunction &CGF, const FunctionDecl *FD) {
}

llvm::Constant *calleePtr = EmitFunctionDeclPointer(CGF.CGM, FD);
return CGCallee::forDirect(calleePtr, FD);
return CGCallee::forDirect(calleePtr, GlobalDecl(FD));
}

CGCallee CodeGenFunction::EmitCallee(const Expr *E) {
Expand Down Expand Up @@ -4419,8 +4419,13 @@ CGCallee CodeGenFunction::EmitCallee(const Expr *E) {
calleePtr = EmitLValue(E).getPointer();
}
assert(functionType->isFunctionType());
CGCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(),
E->getReferencedDeclOfCallee());

GlobalDecl GD;
if (const auto *VD =
dyn_cast_or_null<VarDecl>(E->getReferencedDeclOfCallee()))
GD = GlobalDecl(VD);

CGCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), GD);
CGCallee callee(calleeInfo, calleePtr);
return callee;
}
Expand Down Expand Up @@ -4605,7 +4610,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
assert(CalleeType->isFunctionPointerType() &&
"Call must have function pointer type!");

const Decl *TargetDecl = OrigCallee.getAbstractInfo().getCalleeDecl();
const Decl *TargetDecl =
OrigCallee.getAbstractInfo().getCalleeDecl().getDecl();

if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
// We can only guarantee that a function is called from the correct
Expand Down
24 changes: 13 additions & 11 deletions clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,

if (MD->isStatic()) {
// The method is static, emit it as we would a regular call.
CGCallee callee = CGCallee::forDirect(CGM.GetAddrOfFunction(MD), MD);
CGCallee callee =
CGCallee::forDirect(CGM.GetAddrOfFunction(MD), GlobalDecl(MD));
return EmitCall(getContext().getPointerType(MD->getType()), callee, CE,
ReturnValue);
}
Expand Down Expand Up @@ -353,13 +354,13 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
else if (!DevirtualizedMethod)
Callee = CGCallee::forDirect(
CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty),
Dtor);
GlobalDecl(Dtor, Dtor_Complete));
else {
const CXXDestructorDecl *DDtor =
cast<CXXDestructorDecl>(DevirtualizedMethod);
Callee = CGCallee::forDirect(
CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty),
DDtor);
CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty),
GlobalDecl(DDtor, Dtor_Complete));
}
EmitCXXMemberOrOperatorCall(
CalleeDecl, Callee, ReturnValue, This.getPointer(),
Expand All @@ -371,8 +372,8 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
CGCallee Callee;
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
Callee = CGCallee::forDirect(
CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty),
Ctor);
CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty),
GlobalDecl(Ctor, Ctor_Complete));
} else if (UseVirtualCall) {
Callee = CGCallee::forVirtual(CE, MD, This.getAddress(), Ty);
} else {
Expand All @@ -389,11 +390,12 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
else if (!DevirtualizedMethod)
Callee = CGCallee::forDirect(CGM.GetAddrOfFunction(MD, Ty), MD);
Callee =
CGCallee::forDirect(CGM.GetAddrOfFunction(MD, Ty), GlobalDecl(MD));
else {
Callee = CGCallee::forDirect(
CGM.GetAddrOfFunction(DevirtualizedMethod, Ty),
DevirtualizedMethod);
Callee =
CGCallee::forDirect(CGM.GetAddrOfFunction(DevirtualizedMethod, Ty),
GlobalDecl(DevirtualizedMethod));
}
}

Expand Down Expand Up @@ -1293,7 +1295,7 @@ static RValue EmitNewDeleteCall(CodeGenFunction &CGF,
const CallArgList &Args) {
llvm::Instruction *CallOrInvoke;
llvm::Constant *CalleePtr = CGF.CGM.GetAddrOfFunction(CalleeDecl);
CGCallee Callee = CGCallee::forDirect(CalleePtr, CalleeDecl);
CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(CalleeDecl));
RValue RV =
CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(
Args, CalleeType, /*chainCall=*/false),
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGNonTrivialStruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ template <class Derived> struct GenFuncBase {
llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
F->setVisibility(llvm::GlobalValue::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(nullptr, FI, F);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
IdentifierInfo *II = &Ctx.Idents.get(FuncName);
FunctionDecl *FD = FunctionDecl::Create(
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/CGVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
CGM.ErrorUnsupported(
MD, "non-trivial argument copy for return-adjusting thunk");
}
EmitMustTailThunk(MD, AdjustedThisPtr, CalleePtr);
EmitMustTailThunk(CurGD, AdjustedThisPtr, CalleePtr);
return;
}

Expand Down Expand Up @@ -356,7 +356,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,

// Now emit our call.
llvm::Instruction *CallOrInvoke;
CGCallee Callee = CGCallee::forDirect(CalleePtr, MD);
CGCallee Callee = CGCallee::forDirect(CalleePtr, CurGD);
RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, &CallOrInvoke);

// Consider return adjustment if we have ThunkInfo.
Expand All @@ -375,7 +375,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
FinishThunk();
}

void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD,
void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
llvm::Value *AdjustedThisPtr,
llvm::Value *CalleePtr) {
// Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
Expand Down Expand Up @@ -412,7 +412,7 @@ void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD,
// Apply the standard set of call attributes.
unsigned CallingConv;
llvm::AttributeList Attrs;
CGM.ConstructAttributeList(CalleePtr->getName(), *CurFnInfo, MD, Attrs,
CGM.ConstructAttributeList(CalleePtr->getName(), *CurFnInfo, GD, Attrs,
CallingConv, /*AttrOnCallSite=*/true);
Call->setAttributes(Attrs);
Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2291,7 +2291,7 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures,
// Now build up the set of caller features and verify that all the required
// features are there.
llvm::StringMap<bool> CallerFeatureMap;
CGM.getFunctionFeatureMap(CallerFeatureMap, FD);
CGM.getFunctionFeatureMap(CallerFeatureMap, GlobalDecl().getWithDecl(FD));

// If we have at least one of the features in the feature list return
// true, otherwise return false.
Expand Down
Loading

0 comments on commit de6480a

Please sign in to comment.