|
@@ -502,22 +502,34 @@ bool Constant::needsRelocation() const {
|
|
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
|
|
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
|
|
return BA->getFunction()->needsRelocation();
|
|
return BA->getFunction()->needsRelocation();
|
|
|
|
|
|
- // While raw uses of blockaddress need to be relocated, differences between
|
|
|
|
- // two of them don't when they are for labels in the same function. This is a
|
|
|
|
- // common idiom when creating a table for the indirect goto extension, so we
|
|
|
|
- // handle it efficiently here.
|
|
|
|
- if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this))
|
|
|
|
|
|
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
|
|
if (CE->getOpcode() == Instruction::Sub) {
|
|
if (CE->getOpcode() == Instruction::Sub) {
|
|
ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
|
|
ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
|
|
ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
|
|
ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
|
|
if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
|
|
if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
|
|
- RHS->getOpcode() == Instruction::PtrToInt &&
|
|
|
|
- isa<BlockAddress>(LHS->getOperand(0)) &&
|
|
|
|
- isa<BlockAddress>(RHS->getOperand(0)) &&
|
|
|
|
- cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
|
|
|
|
- cast<BlockAddress>(RHS->getOperand(0))->getFunction())
|
|
|
|
- return false;
|
|
|
|
|
|
+ RHS->getOpcode() == Instruction::PtrToInt) {
|
|
|
|
+ Constant *LHSOp0 = LHS->getOperand(0);
|
|
|
|
+ Constant *RHSOp0 = RHS->getOperand(0);
|
|
|
|
+
|
|
|
|
+ // While raw uses of blockaddress need to be relocated, differences
|
|
|
|
+ // between two of them don't when they are for labels in the same
|
|
|
|
+ // function. This is a common idiom when creating a table for the
|
|
|
|
+ // indirect goto extension, so we handle it efficiently here.
|
|
|
|
+ if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(LHSOp0) &&
|
|
|
|
+ cast<BlockAddress>(LHSOp0)->getFunction() ==
|
|
|
|
+ cast<BlockAddress>(RHSOp0)->getFunction())
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ // Relative pointers do not need to be dynamically relocated.
|
|
|
|
+ if (auto *LHSGV = dyn_cast<GlobalValue>(
|
|
|
|
+ LHSOp0->stripPointerCastsNoFollowAliases()))
|
|
|
|
+ if (auto *RHSGV = dyn_cast<GlobalValue>(
|
|
|
|
+ RHSOp0->stripPointerCastsNoFollowAliases()))
|
|
|
|
+ if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
bool Result = false;
|
|
bool Result = false;
|
|
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
|
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|