diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2019-07-18 20:56:21 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2019-07-18 20:56:21 +0000 |
commit | d1ec8eb84f7f576d00358fcbbeacd457a4b73c43 (patch) | |
tree | 5ca3a2c63eafbf8ba30588fe66d46e788142a968 /llvm/lib/IR/Constants.cpp | |
parent | 956761adb0ffdf6be50018aea1fb804ecb2da9f2 (diff) | |
download | llvm-d1ec8eb84f7f576d00358fcbbeacd457a4b73c43.zip llvm-d1ec8eb84f7f576d00358fcbbeacd457a4b73c43.tar.gz llvm-d1ec8eb84f7f576d00358fcbbeacd457a4b73c43.tar.bz2 |
IR: Teach Constant::needsRelocation() that relative pointers don't need to be relocated.
This causes sections with relative pointers to be marked as read only,
which means that they won't end up sharing pages with writable data.
Differential Revision: https://reviews.llvm.org/D64948
llvm-svn: 366494
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index ff551da..796703e 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -502,22 +502,34 @@ bool Constant::needsRelocation() const { if (const BlockAddress *BA = dyn_cast<BlockAddress>(this)) 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) { ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0)); ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1)); 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; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) |