[IR] move nomerge attribute from function declaration/definition to callsites
Move nomerge attribute from function declaration/definition to callsites to allow virtual function calls attach the attribute. Differential Revision: https://reviews.llvm.org/D94537
This commit is contained in:
parent
6cd44b204c
commit
e53bbd9951
|
@ -1985,7 +1985,9 @@ void CodeGenModule::ConstructAttributeList(
|
|||
FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
|
||||
NBA = Fn->getAttr<NoBuiltinAttr>();
|
||||
}
|
||||
if (!AttrOnCallSite && TargetDecl->hasAttr<NoMergeAttr>())
|
||||
// Only place nomerge attribute on call sites, never functions. This
|
||||
// allows it to work on indirect virtual function calls.
|
||||
if (AttrOnCallSite && TargetDecl->hasAttr<NoMergeAttr>())
|
||||
FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
|
||||
}
|
||||
|
||||
|
@ -5018,13 +5020,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
|||
Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex,
|
||||
llvm::Attribute::StrictFP);
|
||||
|
||||
// Add nomerge attribute to the call-site if the callee function doesn't have
|
||||
// the attribute.
|
||||
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
|
||||
if (!FD->hasAttr<NoMergeAttr>() && InNoMergeAttributedStmt)
|
||||
Attrs = Attrs.addAttribute(getLLVMContext(),
|
||||
llvm::AttributeList::FunctionIndex,
|
||||
llvm::Attribute::NoMerge);
|
||||
// Add call-site nomerge attribute if exists.
|
||||
if (InNoMergeAttributedStmt)
|
||||
Attrs =
|
||||
Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex,
|
||||
llvm::Attribute::NoMerge);
|
||||
|
||||
// Apply some call-site-specific attributes.
|
||||
// TODO: work this into building the attribute set.
|
||||
|
|
|
@ -1772,9 +1772,6 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
|
|||
B.addAttribute(llvm::Attribute::MinSize);
|
||||
}
|
||||
|
||||
if (D->hasAttr<NoMergeAttr>())
|
||||
B.addAttribute(llvm::Attribute::NoMerge);
|
||||
|
||||
F->addAttributes(llvm::AttributeList::FunctionIndex, B);
|
||||
|
||||
unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class A {
|
||||
public:
|
||||
[[clang::nomerge]] A();
|
||||
[[clang::nomerge]] ~A();
|
||||
[[clang::nomerge]] virtual ~A();
|
||||
[[clang::nomerge]] void f();
|
||||
[[clang::nomerge]] virtual void g();
|
||||
[[clang::nomerge]] static void f1();
|
||||
|
@ -14,14 +14,14 @@ public:
|
|||
void g() override;
|
||||
};
|
||||
|
||||
[[clang::nomerge]] bool bar();
|
||||
bool bar();
|
||||
[[clang::nomerge]] void f(bool, bool);
|
||||
|
||||
void foo(int i, A *ap, B *bp) {
|
||||
[[clang::nomerge]] bar();
|
||||
[[clang::nomerge]] (i = 4, bar());
|
||||
[[clang::nomerge]] (void)(bar());
|
||||
[[clang::nomerge]] f(bar(), bar());
|
||||
f(bar(), bar());
|
||||
[[clang::nomerge]] [] { bar(); bar(); }(); // nomerge only applies to the anonymous function call
|
||||
[[clang::nomerge]] for (bar(); bar(); bar()) {}
|
||||
[[clang::nomerge]] { asm("nop"); }
|
||||
|
@ -37,6 +37,9 @@ void foo(int i, A *ap, B *bp) {
|
|||
|
||||
B b;
|
||||
b.g();
|
||||
|
||||
A *newA = new B();
|
||||
delete newA;
|
||||
}
|
||||
|
||||
int g(int i);
|
||||
|
@ -57,37 +60,34 @@ void something_else_again() {
|
|||
g(1);
|
||||
}
|
||||
|
||||
// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0:[0-9]+]]
|
||||
// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
|
||||
// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call void @_Z1fbb({{.*}}){{$}}
|
||||
// CHECK: call void @"_ZZ3fooiP1AP1BENK3$_0clEv"{{.*}} #[[ATTR0:[0-9]+]]
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: call void @_Z1fbb({{.*}}) #[[ATTR0]]
|
||||
// CHECK: call void @"_ZZ3fooiP1AP1BENK3$_0clEv"{{.*}} #[[ATTR0]]
|
||||
// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
|
||||
// CHECK-LABEL: for.cond:
|
||||
// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
|
||||
// CHECK-LABEL: for.inc:
|
||||
// CHECK: call zeroext i1 @_Z3barv() #[[ATTR0]]
|
||||
// CHECK: call void asm sideeffect "nop"{{.*}} #[[ATTR1:[0-9]+]]
|
||||
// CHECK: call zeroext i1 @_Z3barv(){{$}}
|
||||
// CHECK: %[[AG:.*]] = load void (%class.A*)*, void (%class.A*)**
|
||||
// CHECK-NEXT: call void %[[AG]](%class.A* nonnull dereferenceable
|
||||
// CHECK-NEXT: call void %[[AG]](%class.A* {{.*}}) #[[ATTR0]]
|
||||
// CHECK: %[[BG:.*]] = load void (%class.B*)*, void (%class.B*)**
|
||||
// CHECK-NEXT: call void %[[BG]](%class.B* nonnull dereferenceable
|
||||
|
||||
|
||||
// CHECK-DAG: declare zeroext i1 @_Z3barv() #[[ATTR2:[0-9]+]]
|
||||
// CHECK-DAG: declare void @_Z1fbb(i1 zeroext, i1 zeroext) #[[ATTR2]]
|
||||
// CHECK-DAG: declare void @_ZN1AC1Ev{{.*}} #[[ATTR2]]
|
||||
// CHECK-DAG: declare void @_ZN1A1fEv{{.*}} #[[ATTR2]]
|
||||
// CHECK-DAG: declare void @_ZN1A1gEv{{.*}} #[[ATTR2]]
|
||||
// CHECK-DAG: declare void @_ZN1A2f1Ev{{.*}} #[[ATTR2]]
|
||||
// CHECK-DAG: declare void @_ZN1AC2Ev{{.*}} #[[ATTR2]]
|
||||
// CHECK-DAG: declare void @_ZN1AD1Ev{{.*}} #[[ATTR3:[0-9]+]]
|
||||
// CHECK-DAG: declare void @_ZN1AD2Ev{{.*}} #[[ATTR3]]
|
||||
// CHECK-DAG: define{{.*}} i32 @_Z1gi(i32 %i) #[[ATTR4:[0-9]+]] {
|
||||
// CHECK: call void @_ZN1AC1Ev({{.*}}) #[[ATTR0]]
|
||||
// CHECK: call void @_ZN1A1fEv({{.*}}) #[[ATTR0]]
|
||||
// CHECK: call void @_ZN1A1gEv({{.*}}) #[[ATTR0]]
|
||||
// CHECK: call void @_ZN1A2f1Ev() #[[ATTR0]]
|
||||
// CHECK: call void @_ZN1BC1Ev({{.*}}){{$}}
|
||||
// CHECK: call void @_ZN1B1gEv({{.*}}){{$}}
|
||||
// CHECK: call void @_ZN1BC1Ev({{.*}}){{$}}
|
||||
// CHECK: %[[AG:.*]] = load void (%class.A*)*, void (%class.A*)**
|
||||
// CHECK-NEXT: call void %[[AG]](%class.A* {{.*}}) #[[ATTR1]]
|
||||
// CHECK: call void @_ZN1AD1Ev(%class.A* {{.*}}) #[[ATTR1]]
|
||||
|
||||
// CHECK-DAG: attributes #[[ATTR0]] = {{{.*}}nomerge{{.*}}}
|
||||
// CHECK-DAG: attributes #[[ATTR1]] = {{{.*}}nomerge{{.*}}}
|
||||
// CHECK-DAG: attributes #[[ATTR2]] = {{{.*}}nomerge{{.*}}}
|
||||
// CHECK-DAG: attributes #[[ATTR3]] = {{{.*}}nomerge{{.*}}}
|
||||
// CHECK-DAG: attributes #[[ATTR4]] = {{{.*}}nomerge{{.*}}}
|
||||
|
|
Loading…
Reference in New Issue