1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[NPM] Port -mergereturn to NPM

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D89781
This commit is contained in:
Ta-Wei Tu 2020-10-20 10:32:28 -07:00 committed by Arthur Eubanks
parent f50dd85440
commit 516d548dc2
7 changed files with 38 additions and 17 deletions

View File

@ -428,7 +428,7 @@ void initializeThreadSanitizerLegacyPassPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
void initializeTypePromotionPass(PassRegistry&);
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
void initializeUnifyFunctionExitNodesLegacyPassPass(PassRegistry &);
void initializeUnifyLoopExitsPass(PassRegistry &);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry&);

View File

@ -14,19 +14,17 @@
#ifndef LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
#define LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
class BasicBlock;
class UnifyFunctionExitNodes : public FunctionPass {
bool unifyUnreachableBlocks(Function &F);
bool unifyReturnBlocks(Function &F);
class UnifyFunctionExitNodesLegacyPass : public FunctionPass {
public:
static char ID; // Pass identification, replacement for typeid
UnifyFunctionExitNodes();
UnifyFunctionExitNodesLegacyPass();
// We can preserve non-critical-edgeness when we unify function exit nodes
void getAnalysisUsage(AnalysisUsage &AU) const override;
@ -36,6 +34,12 @@ public:
Pass *createUnifyFunctionExitNodesPass();
class UnifyFunctionExitNodesPass
: public PassInfoMixin<UnifyFunctionExitNodesPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H

View File

@ -212,6 +212,7 @@
#include "llvm/Transforms/Utils/StripGCRelocates.h"
#include "llvm/Transforms/Utils/StripNonLineTableDebugInfo.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Vectorize/LoadStoreVectorizer.h"
#include "llvm/Transforms/Vectorize/LoopVectorize.h"
#include "llvm/Transforms/Vectorize/SLPVectorizer.h"

View File

@ -240,6 +240,7 @@ FUNCTION_PASS("lowerswitch", LowerSwitchPass())
FUNCTION_PASS("mem2reg", PromotePass())
FUNCTION_PASS("memcpyopt", MemCpyOptPass())
FUNCTION_PASS("mergeicmps", MergeICmpsPass())
FUNCTION_PASS("mergereturn", UnifyFunctionExitNodesPass())
FUNCTION_PASS("nary-reassociate", NaryReassociatePass())
FUNCTION_PASS("newgvn", NewGVNPass())
FUNCTION_PASS("jump-threading", JumpThreadingPass())

View File

@ -20,28 +20,33 @@
#include "llvm/Transforms/Utils.h"
using namespace llvm;
char UnifyFunctionExitNodes::ID = 0;
char UnifyFunctionExitNodesLegacyPass::ID = 0;
UnifyFunctionExitNodes::UnifyFunctionExitNodes() : FunctionPass(ID) {
initializeUnifyFunctionExitNodesPass(*PassRegistry::getPassRegistry());
UnifyFunctionExitNodesLegacyPass::UnifyFunctionExitNodesLegacyPass()
: FunctionPass(ID) {
initializeUnifyFunctionExitNodesLegacyPassPass(
*PassRegistry::getPassRegistry());
}
INITIALIZE_PASS(UnifyFunctionExitNodes, "mergereturn",
INITIALIZE_PASS(UnifyFunctionExitNodesLegacyPass, "mergereturn",
"Unify function exit nodes", false, false)
Pass *llvm::createUnifyFunctionExitNodesPass() {
return new UnifyFunctionExitNodes();
return new UnifyFunctionExitNodesLegacyPass();
}
void UnifyFunctionExitNodes::getAnalysisUsage(AnalysisUsage &AU) const{
void UnifyFunctionExitNodesLegacyPass::getAnalysisUsage(
AnalysisUsage &AU) const {
// We preserve the non-critical-edgeness property
AU.addPreservedID(BreakCriticalEdgesID);
// This is a cluster of orthogonal Transforms
AU.addPreservedID(LowerSwitchID);
}
bool UnifyFunctionExitNodes::unifyUnreachableBlocks(Function &F) {
std::vector<BasicBlock*> UnreachableBlocks;
namespace {
bool unifyUnreachableBlocks(Function &F) {
std::vector<BasicBlock *> UnreachableBlocks;
for (BasicBlock &I : F)
if (isa<UnreachableInst>(I.getTerminator()))
@ -62,7 +67,7 @@ bool UnifyFunctionExitNodes::unifyUnreachableBlocks(Function &F) {
return true;
}
bool UnifyFunctionExitNodes::unifyReturnBlocks(Function &F) {
bool unifyReturnBlocks(Function &F) {
std::vector<BasicBlock *> ReturningBlocks;
for (BasicBlock &I : F)
@ -103,13 +108,22 @@ bool UnifyFunctionExitNodes::unifyReturnBlocks(Function &F) {
return true;
}
} // namespace
// Unify all exit nodes of the CFG by creating a new BasicBlock, and converting
// all returns to unconditional branches to this new basic block. Also, unify
// all unreachable blocks.
bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
bool UnifyFunctionExitNodesLegacyPass::runOnFunction(Function &F) {
bool Changed = false;
Changed |= unifyUnreachableBlocks(F);
Changed |= unifyReturnBlocks(F);
return Changed;
}
PreservedAnalyses UnifyFunctionExitNodesPass::run(Function &F,
FunctionAnalysisManager &AM) {
bool Changed = false;
Changed |= unifyUnreachableBlocks(F);
Changed |= unifyReturnBlocks(F);
return Changed ? PreservedAnalyses() : PreservedAnalyses::all();
}

View File

@ -38,7 +38,7 @@ void llvm::initializeTransformUtils(PassRegistry &Registry) {
initializeNameAnonGlobalLegacyPassPass(Registry);
initializePromoteLegacyPassPass(Registry);
initializeStripNonLineTableDebugLegacyPassPass(Registry);
initializeUnifyFunctionExitNodesPass(Registry);
initializeUnifyFunctionExitNodesLegacyPassPass(Registry);
initializeMetaRenamerPass(Registry);
initializeStripGCRelocatesLegacyPass(Registry);
initializePredicateInfoPrinterLegacyPassPass(Registry);

View File

@ -1,4 +1,5 @@
; RUN: opt -mergereturn -enable-new-pm=0 -S < %s | FileCheck %s
; RUN: opt -passes='break-crit-edges,lowerswitch,mergereturn' -S < %s | FileCheck %s
; The pass did previously not report the correct Modified status in the case
; where a function had at most one return block, and an unified unreachable