summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp61
1 files changed, 15 insertions, 46 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 15b64ef1173..bfff368a8fe 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -3072,41 +3072,8 @@ static bool allUsersAreInFunction(const Value *V, const Function *F) {
return true;
}
-/// Return true if all users of V are within some (any) function, looking through
-/// ConstantExprs. In other words, are there any global constant users?
-static bool allUsersAreInFunctions(const Value *V) {
- SmallVector<const User*,4> Worklist;
- for (auto *U : V->users())
- Worklist.push_back(U);
- while (!Worklist.empty()) {
- auto *U = Worklist.pop_back_val();
- if (isa<ConstantExpr>(U)) {
- for (auto *UU : U->users())
- Worklist.push_back(UU);
- continue;
- }
-
- if (!isa<Instruction>(U))
- return false;
- }
- return true;
-}
-
-// Return true if T is an integer, float or an array/vector of either.
-static bool isSimpleType(Type *T) {
- if (T->isIntegerTy() || T->isFloatingPointTy())
- return true;
- Type *SubT = nullptr;
- if (T->isArrayTy())
- SubT = T->getArrayElementType();
- else if (T->isVectorTy())
- SubT = T->getVectorElementType();
- else
- return false;
- return SubT->isIntegerTy() || SubT->isFloatingPointTy();
-}
-
-static SDValue promoteToConstantPool(const GlobalValue *GV, SelectionDAG &DAG,
+static SDValue promoteToConstantPool(const ARMTargetLowering *TLI,
+ const GlobalValue *GV, SelectionDAG &DAG,
EVT PtrVT, const SDLoc &dl) {
// If we're creating a pool entry for a constant global with unnamed address,
// and the global is small enough, we can emit it inline into the constant pool
@@ -3133,11 +3100,11 @@ static SDValue promoteToConstantPool(const GlobalValue *GV, SelectionDAG &DAG,
!GVar->hasLocalLinkage())
return SDValue();
- // Ensure that we don't try and inline any type that contains pointers. If
- // we inline a value that contains relocations, we move the relocations from
- // .data to .text which is not ideal.
+ // If we inline a value that contains relocations, we move the relocations
+ // from .data to .text. This is not allowed in position-independent code.
auto *Init = GVar->getInitializer();
- if (!isSimpleType(Init->getType()))
+ if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
+ Init->needsRelocation())
return SDValue();
// The constant islands pass can only really deal with alignment requests
@@ -3169,12 +3136,14 @@ static SDValue promoteToConstantPool(const GlobalValue *GV, SelectionDAG &DAG,
ConstpoolPromotionMaxTotal)
return SDValue();
- // This is only valid if all users are in a single function OR it has users
- // in multiple functions but it no larger than a pointer. We also check if
- // GVar has constant (non-ConstantExpr) users. If so, it essentially has its
- // address taken.
- if (!allUsersAreInFunction(GVar, &F) &&
- !(Size <= 4 && allUsersAreInFunctions(GVar)))
+ // This is only valid if all users are in a single function; we can't clone
+ // the constant in general. The LLVM IR unnamed_addr allows merging
+ // constants, but not cloning them.
+ //
+ // We could potentially allow cloning if we could prove all uses of the
+ // constant in the current function don't care about the address, like
+ // printf format strings. But that isn't implemented for now.
+ if (!allUsersAreInFunction(GVar, &F))
return SDValue();
// We're going to inline this global. Pad it out if needed.
@@ -3230,7 +3199,7 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
// promoteToConstantPool only if not generating XO text section
if (TM.shouldAssumeDSOLocal(*GV->getParent(), GV) && !Subtarget->genExecuteOnly())
- if (SDValue V = promoteToConstantPool(GV, DAG, PtrVT, dl))
+ if (SDValue V = promoteToConstantPool(this, GV, DAG, PtrVT, dl))
return V;
if (isPositionIndependent()) {
OpenPOWER on IntegriCloud