summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp89
1 files changed, 66 insertions, 23 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 947facc87b71..dbdcfe0b6f0b 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -166,8 +167,10 @@ void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<StackProtector>();
AU.addRequired<TargetPassConfig>();
AU.addRequired<GISelCSEAnalysisWrapperPass>();
- if (OptLevel != CodeGenOpt::None)
+ if (OptLevel != CodeGenOpt::None) {
AU.addRequired<BranchProbabilityInfoWrapperPass>();
+ AU.addRequired<AAResultsWrapperPass>();
+ }
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addPreserved<TargetLibraryInfoWrapperPass>();
getSelectionDAGFallbackAnalysisUsage(AU);
@@ -684,7 +687,7 @@ bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) {
BranchProbabilityInfo *BPI = FuncInfo.BPI;
CaseClusterVector Clusters;
Clusters.reserve(SI.getNumCases());
- for (auto &I : SI.cases()) {
+ for (const auto &I : SI.cases()) {
MachineBasicBlock *Succ = &getMBB(*I.getCaseSuccessor());
assert(Succ && "Could not find successor mbb in mapping");
const ConstantInt *CaseVal = I.getCaseValue();
@@ -1275,26 +1278,41 @@ static bool isSwiftError(const Value *V) {
bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
const LoadInst &LI = cast<LoadInst>(U);
- if (DL->getTypeStoreSize(LI.getType()) == 0)
+
+ unsigned StoreSize = DL->getTypeStoreSize(LI.getType());
+ if (StoreSize == 0)
return true;
ArrayRef<Register> Regs = getOrCreateVRegs(LI);
ArrayRef<uint64_t> Offsets = *VMap.getOffsets(LI);
Register Base = getOrCreateVReg(*LI.getPointerOperand());
+ AAMDNodes AAInfo = LI.getAAMetadata();
- Type *OffsetIRTy = DL->getIntPtrType(LI.getPointerOperandType());
+ const Value *Ptr = LI.getPointerOperand();
+ Type *OffsetIRTy = DL->getIntPtrType(Ptr->getType());
LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
- if (CLI->supportSwiftError() && isSwiftError(LI.getPointerOperand())) {
+ if (CLI->supportSwiftError() && isSwiftError(Ptr)) {
assert(Regs.size() == 1 && "swifterror should be single pointer");
- Register VReg = SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.getMBB(),
- LI.getPointerOperand());
+ Register VReg =
+ SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.getMBB(), Ptr);
MIRBuilder.buildCopy(Regs[0], VReg);
return true;
}
auto &TLI = *MF->getSubtarget().getTargetLowering();
MachineMemOperand::Flags Flags = TLI.getLoadMemOperandFlags(LI, *DL);
+ if (AA && !(Flags & MachineMemOperand::MOInvariant)) {
+ if (AA->pointsToConstantMemory(
+ MemoryLocation(Ptr, LocationSize::precise(StoreSize), AAInfo))) {
+ Flags |= MachineMemOperand::MOInvariant;
+
+ // FIXME: pointsToConstantMemory probably does not imply dereferenceable,
+ // but the previous usage implied it did. Probably should check
+ // isDereferenceableAndAlignedPointer.
+ Flags |= MachineMemOperand::MODereferenceable;
+ }
+ }
const MDNode *Ranges =
Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
@@ -1306,7 +1324,7 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
Align BaseAlign = getMemOpAlign(LI);
auto MMO = MF->getMachineMemOperand(
Ptr, Flags, MRI->getType(Regs[i]),
- commonAlignment(BaseAlign, Offsets[i] / 8), LI.getAAMetadata(), Ranges,
+ commonAlignment(BaseAlign, Offsets[i] / 8), AAInfo, Ranges,
LI.getSyncScopeID(), LI.getOrdering());
MIRBuilder.buildLoad(Regs[i], Addr, *MMO);
}
@@ -1400,7 +1418,7 @@ bool IRTranslator::translateInsertValue(const User &U,
ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
ArrayRef<Register> SrcRegs = getOrCreateVRegs(*Src);
ArrayRef<Register> InsertedRegs = getOrCreateVRegs(*U.getOperand(1));
- auto InsertedIt = InsertedRegs.begin();
+ auto *InsertedIt = InsertedRegs.begin();
for (unsigned i = 0; i < DstRegs.size(); ++i) {
if (DstOffsets[i] >= Offset && InsertedIt != InsertedRegs.end())
@@ -1563,9 +1581,9 @@ bool IRTranslator::translateGetElementPtr(const User &U,
bool IRTranslator::translateMemFunc(const CallInst &CI,
MachineIRBuilder &MIRBuilder,
unsigned Opcode) {
-
+ const Value *SrcPtr = CI.getArgOperand(1);
// If the source is undef, then just emit a nop.
- if (isa<UndefValue>(CI.getArgOperand(1)))
+ if (isa<UndefValue>(SrcPtr))
return true;
SmallVector<Register, 3> SrcRegs;
@@ -1595,15 +1613,20 @@ bool IRTranslator::translateMemFunc(const CallInst &CI,
unsigned IsVol =
cast<ConstantInt>(CI.getArgOperand(CI.arg_size() - 1))->getZExtValue();
+ ConstantInt *CopySize = nullptr;
+
if (auto *MCI = dyn_cast<MemCpyInst>(&CI)) {
DstAlign = MCI->getDestAlign().valueOrOne();
SrcAlign = MCI->getSourceAlign().valueOrOne();
+ CopySize = dyn_cast<ConstantInt>(MCI->getArgOperand(2));
} else if (auto *MCI = dyn_cast<MemCpyInlineInst>(&CI)) {
DstAlign = MCI->getDestAlign().valueOrOne();
SrcAlign = MCI->getSourceAlign().valueOrOne();
+ CopySize = dyn_cast<ConstantInt>(MCI->getArgOperand(2));
} else if (auto *MMI = dyn_cast<MemMoveInst>(&CI)) {
DstAlign = MMI->getDestAlign().valueOrOne();
SrcAlign = MMI->getSourceAlign().valueOrOne();
+ CopySize = dyn_cast<ConstantInt>(MMI->getArgOperand(2));
} else {
auto *MSI = cast<MemSetInst>(&CI);
DstAlign = MSI->getDestAlign().valueOrOne();
@@ -1617,14 +1640,31 @@ bool IRTranslator::translateMemFunc(const CallInst &CI,
}
// Create mem operands to store the alignment and volatile info.
- auto VolFlag = IsVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone;
- ICall.addMemOperand(MF->getMachineMemOperand(
- MachinePointerInfo(CI.getArgOperand(0)),
- MachineMemOperand::MOStore | VolFlag, 1, DstAlign));
+ MachineMemOperand::Flags LoadFlags = MachineMemOperand::MOLoad;
+ MachineMemOperand::Flags StoreFlags = MachineMemOperand::MOStore;
+ if (IsVol) {
+ LoadFlags |= MachineMemOperand::MOVolatile;
+ StoreFlags |= MachineMemOperand::MOVolatile;
+ }
+
+ AAMDNodes AAInfo = CI.getAAMetadata();
+ if (AA && CopySize &&
+ AA->pointsToConstantMemory(MemoryLocation(
+ SrcPtr, LocationSize::precise(CopySize->getZExtValue()), AAInfo))) {
+ LoadFlags |= MachineMemOperand::MOInvariant;
+
+ // FIXME: pointsToConstantMemory probably does not imply dereferenceable,
+ // but the previous usage implied it did. Probably should check
+ // isDereferenceableAndAlignedPointer.
+ LoadFlags |= MachineMemOperand::MODereferenceable;
+ }
+
+ ICall.addMemOperand(
+ MF->getMachineMemOperand(MachinePointerInfo(CI.getArgOperand(0)),
+ StoreFlags, 1, DstAlign, AAInfo));
if (Opcode != TargetOpcode::G_MEMSET)
ICall.addMemOperand(MF->getMachineMemOperand(
- MachinePointerInfo(CI.getArgOperand(1)),
- MachineMemOperand::MOLoad | VolFlag, 1, SrcAlign));
+ MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
return true;
}
@@ -1785,7 +1825,7 @@ bool IRTranslator::translateSimpleIntrinsic(const CallInst &CI,
// Yes. Let's translate it.
SmallVector<llvm::SrcOp, 4> VRegs;
- for (auto &Arg : CI.args())
+ for (const auto &Arg : CI.args())
VRegs.push_back(getOrCreateVReg(*Arg));
MIRBuilder.buildInstr(Op, {getOrCreateVReg(CI)}, VRegs,
@@ -2305,7 +2345,7 @@ bool IRTranslator::translateCallBase(const CallBase &CB,
SmallVector<ArrayRef<Register>, 8> Args;
Register SwiftInVReg = 0;
Register SwiftErrorVReg = 0;
- for (auto &Arg : CB.args()) {
+ for (const auto &Arg : CB.args()) {
if (CLI->supportSwiftError() && isSwiftError(Arg)) {
assert(SwiftInVReg == 0 && "Expected only one swift error argument");
LLT Ty = getLLTForType(*Arg->getType(), *DL);
@@ -2394,7 +2434,7 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
if (isa<FPMathOperator>(CI))
MIB->copyIRFlags(CI);
- for (auto &Arg : enumerate(CI.args())) {
+ for (const auto &Arg : enumerate(CI.args())) {
// If this is required to be an immediate, don't materialize it in a
// register.
if (CI.paramHasAttr(Arg.index(), Attribute::ImmArg)) {
@@ -2947,7 +2987,7 @@ void IRTranslator::finishPendingPhis() {
for (unsigned i = 0; i < PI->getNumIncomingValues(); ++i) {
auto IRPred = PI->getIncomingBlock(i);
ArrayRef<Register> ValRegs = getOrCreateVRegs(*PI->getIncomingValue(i));
- for (auto Pred : getMachinePredBBs({IRPred, PI->getParent()})) {
+ for (auto *Pred : getMachinePredBBs({IRPred, PI->getParent()})) {
if (SeenPreds.count(Pred) || !PhiMBB->isPredecessor(Pred))
continue;
SeenPreds.insert(Pred);
@@ -3347,10 +3387,13 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
TM.resetTargetOptions(F);
EnableOpts = OptLevel != CodeGenOpt::None && !skipFunction(F);
FuncInfo.MF = MF;
- if (EnableOpts)
+ if (EnableOpts) {
+ AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
FuncInfo.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
- else
+ } else {
+ AA = nullptr;
FuncInfo.BPI = nullptr;
+ }
FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);