mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[NewPM] Port -separate-const-offset-from-gep
Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D91095
This commit is contained in:
parent
77d0891b19
commit
280b8ab920
@ -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&);
|
||||
|
27
include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h
Normal file
27
include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h
Normal 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
|
@ -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"
|
||||
|
@ -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())
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user