1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[NewPM] Port -separate-const-offset-from-gep

Reviewed By: asbirlea

Differential Revision: https://reviews.llvm.org/D91095
This commit is contained in:
Arthur Eubanks 2020-11-09 11:40:49 -08:00
parent 77d0891b19
commit 280b8ab920
7 changed files with 92 additions and 22 deletions

View File

@ -392,7 +392,7 @@ void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
void initializeScalarizerLegacyPassPass(PassRegistry&);
void initializeScavengerTestPass(PassRegistry&);
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&);
void initializeSeparateConstOffsetFromGEPPass(PassRegistry&);
void initializeSeparateConstOffsetFromGEPLegacyPassPass(PassRegistry &);
void initializeShadowStackGCLoweringPass(PassRegistry&);
void initializeShrinkWrapPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&);

View File

@ -0,0 +1,27 @@
//===- SeparateConstOffsetFromGEP.h ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
#define LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
#include "llvm/IR/PassManager.h"
namespace llvm {
class SeparateConstOffsetFromGEPPass
: public PassInfoMixin<SeparateConstOffsetFromGEPPass> {
bool LowerGEP;
public:
SeparateConstOffsetFromGEPPass(bool LowerGEP = false) : LowerGEP(LowerGEP) {}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
};
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H

View File

@ -189,6 +189,7 @@
#include "llvm/Transforms/Scalar/SCCP.h"
#include "llvm/Transforms/Scalar/SROA.h"
#include "llvm/Transforms/Scalar/Scalarizer.h"
#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Scalar/Sink.h"

View File

@ -285,6 +285,7 @@ FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(dbgs()))
FUNCTION_PASS("reassociate", ReassociatePass())
FUNCTION_PASS("reg2mem", RegToMemPass())
FUNCTION_PASS("scalarizer", ScalarizerPass())
FUNCTION_PASS("separate-const-offset-from-gep", SeparateConstOffsetFromGEPPass())
FUNCTION_PASS("sccp", SCCPPass())
FUNCTION_PASS("simplifycfg", SimplifyCFGPass())
FUNCTION_PASS("sink", SinkingPass())

View File

@ -101,7 +101,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeSimpleLoopUnswitchLegacyPassPass(Registry);
initializeSinkingLegacyPassPass(Registry);
initializeTailCallElimPass(Registry);
initializeSeparateConstOffsetFromGEPPass(Registry);
initializeSeparateConstOffsetFromGEPLegacyPassPass(Registry);
initializeSpeculativeExecutionLegacyPassPass(Registry);
initializeStraightLineStrengthReduceLegacyPassPass(Registry);
initializePlaceBackedgeSafepointsImplPass(Registry);

View File

@ -155,6 +155,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
@ -177,6 +178,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
@ -342,13 +344,14 @@ private:
/// A pass that tries to split every GEP in the function into a variadic
/// base and a constant offset. It is a FunctionPass because searching for the
/// constant offset may inspect other basic blocks.
class SeparateConstOffsetFromGEP : public FunctionPass {
class SeparateConstOffsetFromGEPLegacyPass : public FunctionPass {
public:
static char ID;
SeparateConstOffsetFromGEP(bool LowerGEP = false)
SeparateConstOffsetFromGEPLegacyPass(bool LowerGEP = false)
: FunctionPass(ID), LowerGEP(LowerGEP) {
initializeSeparateConstOffsetFromGEPPass(*PassRegistry::getPassRegistry());
initializeSeparateConstOffsetFromGEPLegacyPassPass(
*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@ -360,13 +363,25 @@ public:
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
bool doInitialization(Module &M) override {
DL = &M.getDataLayout();
return false;
}
bool runOnFunction(Function &F) override;
private:
bool LowerGEP;
};
/// A pass that tries to split every GEP in the function into a variadic
/// base and a constant offset. It is a FunctionPass because searching for the
/// constant offset may inspect other basic blocks.
class SeparateConstOffsetFromGEP {
public:
SeparateConstOffsetFromGEP(
DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI,
TargetLibraryInfo *TLI,
function_ref<TargetTransformInfo &(Function &)> GetTTI, bool LowerGEP)
: DT(DT), SE(SE), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {}
bool run(Function &F);
private:
/// Tries to split the given GEP into a variadic base and a constant offset,
/// and returns true if the splitting succeeds.
@ -450,9 +465,10 @@ private:
const DataLayout *DL = nullptr;
DominatorTree *DT = nullptr;
ScalarEvolution *SE;
LoopInfo *LI;
TargetLibraryInfo *TLI;
// Retrieved lazily since not always used.
function_ref<TargetTransformInfo &(Function &)> GetTTI;
/// Whether to lower a GEP with multiple indices into arithmetic operations or
/// multiple GEPs with a single index.
@ -464,10 +480,10 @@ private:
} // end anonymous namespace
char SeparateConstOffsetFromGEP::ID = 0;
char SeparateConstOffsetFromGEPLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(
SeparateConstOffsetFromGEP, "separate-const-offset-from-gep",
SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep",
"Split GEPs to a variadic base and a constant offset for better CSE", false,
false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@ -476,12 +492,12 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(
SeparateConstOffsetFromGEP, "separate-const-offset-from-gep",
SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep",
"Split GEPs to a variadic base and a constant offset for better CSE", false,
false)
FunctionPass *llvm::createSeparateConstOffsetFromGEPPass(bool LowerGEP) {
return new SeparateConstOffsetFromGEP(LowerGEP);
return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
}
bool ConstantOffsetExtractor::CanTraceInto(bool SignExtended,
@ -962,8 +978,7 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
if (!NeedsExtraction)
return Changed;
TargetTransformInfo &TTI =
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*GEP->getFunction());
TargetTransformInfo &TTI = GetTTI(*GEP->getFunction());
// If LowerGEP is disabled, before really splitting the GEP, check whether the
// backend supports the addressing mode we are about to produce. If no, this
@ -1128,17 +1143,25 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
return true;
}
bool SeparateConstOffsetFromGEP::runOnFunction(Function &F) {
bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
auto GetTTI = [this](Function &F) -> TargetTransformInfo & {
return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
};
SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP);
return Impl.run(F);
}
bool SeparateConstOffsetFromGEP::run(Function &F) {
if (DisableSeparateConstOffsetFromGEP)
return false;
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
DL = &F.getParent()->getDataLayout();
bool Changed = false;
for (BasicBlock &B : F) {
for (BasicBlock::iterator I = B.begin(), IE = B.end(); I != IE;)
@ -1345,3 +1368,20 @@ void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *First,
} else
First->setIsInBounds(true);
}
PreservedAnalyses
SeparateConstOffsetFromGEPPass::run(Function &F, FunctionAnalysisManager &AM) {
auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
auto *LI = &AM.getResult<LoopAnalysis>(F);
auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
auto GetTTI = [&AM](Function &F) -> TargetTransformInfo & {
return AM.getResult<TargetIRAnalysis>(F);
};
SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP);
if (!Impl.run(F))
return PreservedAnalyses::all();
PreservedAnalyses PA;
PA.preserveSet<CFGAnalyses>();
return PA;
}

View File

@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -separate-const-offset-from-gep < %s | FileCheck %s
; RUN: opt -S -passes=separate-const-offset-from-gep < %s | FileCheck %s
define void @matchingExtensions(i32* %ap, i32* %bp, i64* %result) {
; CHECK-LABEL: @matchingExtensions(