Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit a784eca

Browse files
authoredNov 28, 2018
Merge pull request #131 from nikic/some-fixes
Misc
2 parents 21a0c9e + 63e77c8 commit a784eca

File tree

6 files changed

+189
-166
lines changed

6 files changed

+189
-166
lines changed
 

‎include/llvm/IR/Instruction.h

-8
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,6 @@ class Instruction : public User,
586586
static_cast<const Instruction *>(this)->getNextNonDebugInstruction());
587587
}
588588

589-
/// Return a pointer to the previous non-debug instruction in the same basic
590-
/// block as 'this', or nullptr if no such instruction exists.
591-
const Instruction *getPrevNonDebugInstruction() const;
592-
Instruction *getPrevNonDebugInstruction() {
593-
return const_cast<Instruction *>(
594-
static_cast<const Instruction *>(this)->getPrevNonDebugInstruction());
595-
}
596-
597589
/// Create a copy of 'this' instruction that is identical in all ways except
598590
/// the following:
599591
/// * The instruction has no parent

‎lib/IR/Instruction.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -602,13 +602,6 @@ const Instruction *Instruction::getNextNonDebugInstruction() const {
602602
return nullptr;
603603
}
604604

605-
const Instruction *Instruction::getPrevNonDebugInstruction() const {
606-
for (const Instruction *I = getPrevNode(); I; I = I->getPrevNode())
607-
if (!isa<DbgInfoIntrinsic>(I))
608-
return I;
609-
return nullptr;
610-
}
611-
612605
bool Instruction::isAssociative() const {
613606
unsigned Opcode = getOpcode();
614607
if (isAssociative(Opcode))

‎lib/Transforms/IPO/MergeFunctions.cpp

+73-14
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ using namespace llvm;
136136

137137
STATISTIC(NumFunctionsMerged, "Number of functions merged");
138138
STATISTIC(NumThunksWritten, "Number of thunks generated");
139+
STATISTIC(NumAliasesWritten, "Number of aliases generated");
139140
STATISTIC(NumDoubleWeak, "Number of new functions created");
140141

141142
static cl::opt<unsigned> NumFunctionsForSanityCheck(
@@ -165,6 +166,11 @@ static cl::opt<bool>
165166
cl::desc("Preserve debug info in thunk when mergefunc "
166167
"transformations are made."));
167168

169+
static cl::opt<bool>
170+
MergeFunctionsAliases("mergefunc-use-aliases", cl::Hidden,
171+
cl::init(false),
172+
cl::desc("Allow mergefunc to create aliases"));
173+
168174
namespace {
169175

170176
class FunctionNode {
@@ -272,6 +278,13 @@ class MergeFunctions : public ModulePass {
272278
/// delete G.
273279
void writeThunk(Function *F, Function *G);
274280

281+
// Replace G with an alias to F (deleting function G)
282+
void writeAlias(Function *F, Function *G);
283+
284+
// Replace G with an alias to F if possible, or a thunk to F if
285+
// profitable. Returns false if neither is the case.
286+
bool writeThunkOrAlias(Function *F, Function *G);
287+
275288
/// Replace function F with function G in the function tree.
276289
void replaceFunctionInTree(const FunctionNode &FN, Function *G);
277290

@@ -735,27 +748,76 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
735748
++NumThunksWritten;
736749
}
737750

751+
// Whether this function may be replaced by an alias
752+
static bool canCreateAliasFor(Function *F) {
753+
if (!MergeFunctionsAliases || !F->hasGlobalUnnamedAddr())
754+
return false;
755+
756+
// We should only see linkages supported by aliases here
757+
assert(F->hasLocalLinkage() || F->hasExternalLinkage()
758+
|| F->hasWeakLinkage() || F->hasLinkOnceLinkage());
759+
return true;
760+
}
761+
762+
// Replace G with an alias to F (deleting function G)
763+
void MergeFunctions::writeAlias(Function *F, Function *G) {
764+
Constant *BitcastF = ConstantExpr::getBitCast(F, G->getType());
765+
PointerType *PtrType = G->getType();
766+
auto *GA = GlobalAlias::create(
767+
PtrType->getElementType(), PtrType->getAddressSpace(),
768+
G->getLinkage(), "", BitcastF, G->getParent());
769+
770+
F->setAlignment(std::max(F->getAlignment(), G->getAlignment()));
771+
GA->takeName(G);
772+
GA->setVisibility(G->getVisibility());
773+
GA->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
774+
775+
removeUsers(G);
776+
G->replaceAllUsesWith(GA);
777+
G->eraseFromParent();
778+
779+
LLVM_DEBUG(dbgs() << "writeAlias: " << GA->getName() << '\n');
780+
++NumAliasesWritten;
781+
}
782+
783+
// Replace G with an alias to F if possible, or a thunk to F if
784+
// profitable. Returns false if neither is the case.
785+
bool MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
786+
if (canCreateAliasFor(G)) {
787+
writeAlias(F, G);
788+
return true;
789+
}
790+
if (isThunkProfitable(F)) {
791+
writeThunk(F, G);
792+
return true;
793+
}
794+
return false;
795+
}
796+
738797
// Merge two equivalent functions. Upon completion, Function G is deleted.
739798
void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
740799
if (F->isInterposable()) {
741800
assert(G->isInterposable());
742801

743-
if (!isThunkProfitable(F)) {
802+
// Both writeThunkOrAlias() calls below must succeed, either because we can
803+
// create aliases for G and NewF, or because a thunk for F is profitable.
804+
// F here has the same signature as NewF below, so that's what we check.
805+
if (!isThunkProfitable(F) && (!canCreateAliasFor(F) || !canCreateAliasFor(G))) {
744806
return;
745807
}
746808

747809
// Make them both thunks to the same internal function.
748-
Function *H = Function::Create(F->getFunctionType(), F->getLinkage(), "",
749-
F->getParent());
750-
H->copyAttributesFrom(F);
751-
H->takeName(F);
810+
Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), "",
811+
F->getParent());
812+
NewF->copyAttributesFrom(F);
813+
NewF->takeName(F);
752814
removeUsers(F);
753-
F->replaceAllUsesWith(H);
815+
F->replaceAllUsesWith(NewF);
754816

755-
unsigned MaxAlignment = std::max(G->getAlignment(), H->getAlignment());
817+
unsigned MaxAlignment = std::max(G->getAlignment(), NewF->getAlignment());
756818

757-
writeThunk(F, G);
758-
writeThunk(F, H);
819+
writeThunkOrAlias(F, G);
820+
writeThunkOrAlias(F, NewF);
759821

760822
F->setAlignment(MaxAlignment);
761823
F->setLinkage(GlobalValue::PrivateLinkage);
@@ -789,12 +851,9 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
789851
return;
790852
}
791853

792-
if (!isThunkProfitable(F)) {
793-
return;
854+
if (writeThunkOrAlias(F, G)) {
855+
++NumFunctionsMerged;
794856
}
795-
796-
writeThunk(F, G);
797-
++NumFunctionsMerged;
798857
}
799858
}
800859

‎lib/Transforms/Utils/SimplifyCFG.cpp

-16
Original file line numberDiff line numberDiff line change
@@ -1372,14 +1372,6 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
13721372
}
13731373
}
13741374

1375-
// As the parent basic block terminator is a branch instruction which is
1376-
// removed at the end of the current transformation, use its previous
1377-
// non-debug instruction, as the reference insertion point, which will
1378-
// provide the debug location for the instruction being hoisted. For BBs
1379-
// with only debug instructions, use an empty debug location.
1380-
Instruction *InsertPt =
1381-
BIParent->getTerminator()->getPrevNonDebugInstruction();
1382-
13831375
// Okay, it is safe to hoist the terminator.
13841376
Instruction *NT = I1->clone();
13851377
BIParent->getInstList().insert(BI->getIterator(), NT);
@@ -1389,14 +1381,6 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
13891381
NT->takeName(I1);
13901382
}
13911383

1392-
// The instruction NT being hoisted, is the terminator for the true branch,
1393-
// with debug location (DILocation) within that branch. We can't retain
1394-
// its original debug location value, otherwise 'select' instructions that
1395-
// are created from any PHI nodes, will take its debug location, giving
1396-
// the impression that those 'select' instructions are in the true branch,
1397-
// causing incorrect stepping, affecting the debug experience.
1398-
NT->setDebugLoc(InsertPt ? InsertPt->getDebugLoc() : DebugLoc());
1399-
14001384
IRBuilder<NoFolder> Builder(NT);
14011385
// Hoisting one of the terminators from our successor is a great thing.
14021386
// Unfortunately, the successors of the if/else blocks may have PHI nodes in

‎test/CodeGen/X86/pr39187-g.ll

-121
This file was deleted.

‎test/Transforms/MergeFunc/alias.ll

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
; RUN: opt -S -mergefunc -mergefunc-use-aliases < %s | FileCheck %s
2+
3+
; Aliases should always be created for the weak functions, and
4+
; for external functions if there is no local function
5+
6+
; CHECK: @external_external_2 = unnamed_addr alias void (float*), bitcast (void (i32*)* @external_external_1 to void (float*)*)
7+
; CHECK: @weak_weak_2 = weak unnamed_addr alias void (float*), bitcast (void (i32*)* @0 to void (float*)*)
8+
; CHECK: @weak_weak_1 = weak unnamed_addr alias void (i32*), void (i32*)* @0
9+
; CHECK: @weak_external_1 = weak unnamed_addr alias void (i32*), bitcast (void (float*)* @weak_external_2 to void (i32*)*)
10+
; CHECK: @external_weak_2 = weak unnamed_addr alias void (float*), bitcast (void (i32*)* @external_weak_1 to void (float*)*)
11+
; CHECK: @weak_internal_1 = weak unnamed_addr alias void (i32*), bitcast (void (float*)* @weak_internal_2 to void (i32*)*)
12+
; CHECK: @internal_weak_2 = weak unnamed_addr alias void (float*), bitcast (void (i32*)* @internal_weak_1 to void (float*)*)
13+
14+
; A strong backing function had to be created for the weak-weak pair
15+
16+
; CHECK: define private void @0(i32* %a) unnamed_addr
17+
; CHECK_NEXT: call void @dummy4()
18+
19+
; These internal functions are dropped in favor of the external ones
20+
21+
; CHECK-NOT: define internal void @external_internal_2(float *%a) unnamed_addr
22+
; CHECK-NOT: define internal void @internal_external_1(i32 *%a) unnamed_addr
23+
; CHECK-NOT: define internal void @internal_external_1(i32 *%a) unnamed_addr
24+
; CHECK-NOT: define internal void @internal_external_2(float *%a) unnamed_addr
25+
26+
; Only used to mark which functions should be merged.
27+
declare void @dummy1()
28+
declare void @dummy2()
29+
declare void @dummy3()
30+
declare void @dummy4()
31+
declare void @dummy5()
32+
declare void @dummy6()
33+
declare void @dummy7()
34+
declare void @dummy8()
35+
declare void @dummy9()
36+
37+
define void @external_external_1(i32 *%a) unnamed_addr {
38+
call void @dummy1()
39+
ret void
40+
}
41+
define void @external_external_2(float *%a) unnamed_addr {
42+
call void @dummy1()
43+
ret void
44+
}
45+
46+
define void @external_internal_1(i32 *%a) unnamed_addr {
47+
call void @dummy2()
48+
ret void
49+
}
50+
define internal void @external_internal_2(float *%a) unnamed_addr {
51+
call void @dummy2()
52+
ret void
53+
}
54+
55+
define internal void @internal_external_1(i32 *%a) unnamed_addr {
56+
call void @dummy3()
57+
ret void
58+
}
59+
define void @internal_external_2(float *%a) unnamed_addr {
60+
call void @dummy3()
61+
ret void
62+
}
63+
64+
define weak void @weak_weak_1(i32 *%a) unnamed_addr {
65+
call void @dummy4()
66+
ret void
67+
}
68+
define weak void @weak_weak_2(float *%a) unnamed_addr {
69+
call void @dummy4()
70+
ret void
71+
}
72+
73+
define weak void @weak_external_1(i32 *%a) unnamed_addr {
74+
call void @dummy5()
75+
ret void
76+
}
77+
define external void @weak_external_2(float *%a) unnamed_addr {
78+
call void @dummy5()
79+
ret void
80+
}
81+
82+
define external void @external_weak_1(i32 *%a) unnamed_addr {
83+
call void @dummy6()
84+
ret void
85+
}
86+
define weak void @external_weak_2(float *%a) unnamed_addr {
87+
call void @dummy6()
88+
ret void
89+
}
90+
91+
define weak void @weak_internal_1(i32 *%a) unnamed_addr {
92+
call void @dummy7()
93+
ret void
94+
}
95+
define internal void @weak_internal_2(float *%a) unnamed_addr {
96+
call void @dummy7()
97+
ret void
98+
}
99+
100+
define internal void @internal_weak_1(i32 *%a) unnamed_addr {
101+
call void @dummy8()
102+
ret void
103+
}
104+
define weak void @internal_weak_2(float *%a) unnamed_addr {
105+
call void @dummy8()
106+
ret void
107+
}
108+
109+
define internal void @internal_internal_1(i32 *%a) unnamed_addr {
110+
call void @dummy9()
111+
ret void
112+
}
113+
define internal void @internal_internal_2(float *%a) unnamed_addr {
114+
call void @dummy9()
115+
ret void
116+
}

0 commit comments

Comments
 (0)
This repository has been archived.