1 //===- GlobalSplit.cpp - global variable splitter -------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass uses inrange annotations on GEP indices to split globals where
10 // beneficial. Clang currently attaches these annotations to references to
11 // virtual table globals under the Itanium ABI for the benefit of the
12 // whole-program virtual call optimization and control flow integrity passes.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/Transforms/IPO/GlobalSplit.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/IR/Constant.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/GlobalValue.h"
24 #include "llvm/IR/GlobalVariable.h"
25 #include "llvm/IR/Intrinsics.h"
26 #include "llvm/IR/LLVMContext.h"
27 #include "llvm/IR/Metadata.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/Operator.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/IR/User.h"
32 #include "llvm/Pass.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Transforms/IPO.h"
40 static bool splitGlobal(GlobalVariable
&GV
) {
41 // If the address of the global is taken outside of the module, we cannot
42 // apply this transformation.
43 if (!GV
.hasLocalLinkage())
46 // We currently only know how to split ConstantStructs.
47 auto *Init
= dyn_cast_or_null
<ConstantStruct
>(GV
.getInitializer());
51 // Verify that each user of the global is an inrange getelementptr constant.
52 // From this it follows that any loads from or stores to that global must use
53 // a pointer derived from an inrange getelementptr constant, which is
54 // sufficient to allow us to apply the splitting transform.
55 for (User
*U
: GV
.users()) {
56 if (!isa
<Constant
>(U
))
59 auto *GEP
= dyn_cast
<GEPOperator
>(U
);
60 if (!GEP
|| !GEP
->getInRangeIndex() || *GEP
->getInRangeIndex() != 1 ||
61 !isa
<ConstantInt
>(GEP
->getOperand(1)) ||
62 !cast
<ConstantInt
>(GEP
->getOperand(1))->isZero() ||
63 !isa
<ConstantInt
>(GEP
->getOperand(2)))
67 SmallVector
<MDNode
*, 2> Types
;
68 GV
.getMetadata(LLVMContext::MD_type
, Types
);
70 const DataLayout
&DL
= GV
.getParent()->getDataLayout();
71 const StructLayout
*SL
= DL
.getStructLayout(Init
->getType());
73 IntegerType
*Int32Ty
= Type::getInt32Ty(GV
.getContext());
75 std::vector
<GlobalVariable
*> SplitGlobals(Init
->getNumOperands());
76 for (unsigned I
= 0; I
!= Init
->getNumOperands(); ++I
) {
77 // Build a global representing this split piece.
79 new GlobalVariable(*GV
.getParent(), Init
->getOperand(I
)->getType(),
80 GV
.isConstant(), GlobalValue::PrivateLinkage
,
81 Init
->getOperand(I
), GV
.getName() + "." + utostr(I
));
82 SplitGlobals
[I
] = SplitGV
;
84 unsigned SplitBegin
= SL
->getElementOffset(I
);
85 unsigned SplitEnd
= (I
== Init
->getNumOperands() - 1)
86 ? SL
->getSizeInBytes()
87 : SL
->getElementOffset(I
+ 1);
89 // Rebuild type metadata, adjusting by the split offset.
90 // FIXME: See if we can use DW_OP_piece to preserve debug metadata here.
91 for (MDNode
*Type
: Types
) {
92 uint64_t ByteOffset
= cast
<ConstantInt
>(
93 cast
<ConstantAsMetadata
>(Type
->getOperand(0))->getValue())
95 // Type metadata may be attached one byte after the end of the vtable, for
96 // classes without virtual methods in Itanium ABI. AFAIK, it is never
97 // attached to the first byte of a vtable. Subtract one to get the right
99 // This is making an assumption that vtable groups are the only kinds of
100 // global variables that !type metadata can be attached to, and that they
101 // are either Itanium ABI vtable groups or contain a single vtable (i.e.
102 // Microsoft ABI vtables).
103 uint64_t AttachedTo
= (ByteOffset
== 0) ? ByteOffset
: ByteOffset
- 1;
104 if (AttachedTo
< SplitBegin
|| AttachedTo
>= SplitEnd
)
106 SplitGV
->addMetadata(
107 LLVMContext::MD_type
,
108 *MDNode::get(GV
.getContext(),
109 {ConstantAsMetadata::get(
110 ConstantInt::get(Int32Ty
, ByteOffset
- SplitBegin
)),
111 Type
->getOperand(1)}));
115 for (User
*U
: GV
.users()) {
116 auto *GEP
= cast
<GEPOperator
>(U
);
117 unsigned I
= cast
<ConstantInt
>(GEP
->getOperand(2))->getZExtValue();
118 if (I
>= SplitGlobals
.size())
121 SmallVector
<Value
*, 4> Ops
;
122 Ops
.push_back(ConstantInt::get(Int32Ty
, 0));
123 for (unsigned I
= 3; I
!= GEP
->getNumOperands(); ++I
)
124 Ops
.push_back(GEP
->getOperand(I
));
126 auto *NewGEP
= ConstantExpr::getGetElementPtr(
127 SplitGlobals
[I
]->getInitializer()->getType(), SplitGlobals
[I
], Ops
,
129 GEP
->replaceAllUsesWith(NewGEP
);
132 // Finally, remove the original global. Any remaining uses refer to invalid
133 // elements of the global, so replace with undef.
135 GV
.replaceAllUsesWith(UndefValue::get(GV
.getType()));
136 GV
.eraseFromParent();
140 static bool splitGlobals(Module
&M
) {
141 // First, see if the module uses either of the llvm.type.test or
142 // llvm.type.checked.load intrinsics, which indicates that splitting globals
143 // may be beneficial.
144 Function
*TypeTestFunc
=
145 M
.getFunction(Intrinsic::getName(Intrinsic::type_test
));
146 Function
*TypeCheckedLoadFunc
=
147 M
.getFunction(Intrinsic::getName(Intrinsic::type_checked_load
));
148 if ((!TypeTestFunc
|| TypeTestFunc
->use_empty()) &&
149 (!TypeCheckedLoadFunc
|| TypeCheckedLoadFunc
->use_empty()))
152 bool Changed
= false;
153 for (auto I
= M
.global_begin(); I
!= M
.global_end();) {
154 GlobalVariable
&GV
= *I
;
156 Changed
|= splitGlobal(GV
);
163 struct GlobalSplit
: public ModulePass
{
166 GlobalSplit() : ModulePass(ID
) {
167 initializeGlobalSplitPass(*PassRegistry::getPassRegistry());
170 bool runOnModule(Module
&M
) override
{
174 return splitGlobals(M
);
178 } // end anonymous namespace
180 char GlobalSplit::ID
= 0;
182 INITIALIZE_PASS(GlobalSplit
, "globalsplit", "Global splitter", false, false)
184 ModulePass
*llvm::createGlobalSplitPass() {
185 return new GlobalSplit
;
188 PreservedAnalyses
GlobalSplitPass::run(Module
&M
, ModuleAnalysisManager
&AM
) {
189 if (!splitGlobals(M
))
190 return PreservedAnalyses::all();
191 return PreservedAnalyses::none();