Use AA in LoadCombine

LoadCombine can be smarter about aborting when a writing instruction is
encountered, instead of aborting upon encountering any writing instruction, use
an AliasSetTracker, and only abort when encountering some write that might
alias with the loads that could potentially be combined.

This was originally motivated by comments made (and a test case provided) by
David Majnemer in response to PR21448. It turned out that LoadCombine was not
responsible for that PR, but LoadCombine should also be improved so that
unrelated stores (and @llvm.assume) don't interrupt load combining.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221203 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel
2014-11-03 23:19:16 +00:00
parent 42090c633f
commit cd9acde7f3
5 changed files with 112 additions and 5 deletions

View File

@ -15,6 +15,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Pass.h"
#include "llvm/IR/DataLayout.h"
@ -51,11 +53,12 @@ struct LoadPOPPair {
class LoadCombine : public BasicBlockPass {
LLVMContext *C;
const DataLayout *DL;
AliasAnalysis *AA;
public:
LoadCombine()
: BasicBlockPass(ID),
C(nullptr), DL(nullptr) {
C(nullptr), DL(nullptr), AA(nullptr) {
initializeSROAPass(*PassRegistry::getPassRegistry());
}
@ -225,19 +228,23 @@ bool LoadCombine::runOnBasicBlock(BasicBlock &BB) {
if (skipOptnoneFunction(BB) || !DL)
return false;
AA = &getAnalysis<AliasAnalysis>();
IRBuilder<true, TargetFolder>
TheBuilder(BB.getContext(), TargetFolder(DL));
Builder = &TheBuilder;
DenseMap<const Value *, SmallVector<LoadPOPPair, 8>> LoadMap;
AliasSetTracker AST(*AA);
bool Combined = false;
unsigned Index = 0;
for (auto &I : BB) {
if (I.mayWriteToMemory() || I.mayThrow()) {
if (I.mayThrow() || (I.mayWriteToMemory() && AST.containsUnknown(&I))) {
if (combineLoads(LoadMap))
Combined = true;
LoadMap.clear();
AST.clear();
continue;
}
LoadInst *LI = dyn_cast<LoadInst>(&I);
@ -250,6 +257,7 @@ bool LoadCombine::runOnBasicBlock(BasicBlock &BB) {
if (!POP.Pointer)
continue;
LoadMap[POP.Pointer].push_back(LoadPOPPair(LI, POP, Index++));
AST.add(LI);
}
if (combineLoads(LoadMap))
Combined = true;
@ -258,6 +266,9 @@ bool LoadCombine::runOnBasicBlock(BasicBlock &BB) {
void LoadCombine::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<AliasAnalysis>();
AU.addPreserved<AliasAnalysis>();
}
char LoadCombine::ID = 0;
@ -266,5 +277,9 @@ BasicBlockPass *llvm::createLoadCombinePass() {
return new LoadCombine();
}
INITIALIZE_PASS(LoadCombine, "load-combine", "Combine Adjacent Loads", false,
false)
INITIALIZE_PASS_BEGIN(LoadCombine, "load-combine", "Combine Adjacent Loads",
false, false)
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
INITIALIZE_PASS_END(LoadCombine, "load-combine", "Combine Adjacent Loads",
false, false)