mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
Summary: DataLayout keeps the string used for its creation. As a side effect it is no longer needed in the Module. This is "almost" NFC, the string is no longer canonicalized, you can't rely on two "equals" DataLayout having the same string returned by getStringRepresentation(). Get rid of DataLayoutPass: the DataLayout is in the Module The DataLayout is "per-module", let's enforce this by not duplicating it more than necessary. One more step toward non-optionality of the DataLayout in the module. Make DataLayout Non-Optional in the Module Module->getDataLayout() will never returns nullptr anymore. Reviewers: echristo Subscribers: resistor, llvm-commits, jholewinski Differential Revision: http://reviews.llvm.org/D7992 From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231270 91177308-0d34-0410-b5e6-96231b3b80d8
118 lines
4.7 KiB
C++
118 lines
4.7 KiB
C++
//===------ SimplifyInstructions.cpp - Remove redundant instructions ------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This is a utility pass used for testing the InstructionSimplify analysis.
|
|
// The analysis is applied to every instruction, and if it simplifies then the
|
|
// instruction is replaced by the simplification. If you are looking for a pass
|
|
// that performs serious instruction folding, use the instcombine pass instead.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/ADT/DepthFirstIterator.h"
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/Analysis/AssumptionCache.h"
|
|
#include "llvm/Analysis/InstructionSimplify.h"
|
|
#include "llvm/IR/DataLayout.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/Type.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
|
#include "llvm/Transforms/Utils/Local.h"
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "instsimplify"
|
|
|
|
STATISTIC(NumSimplified, "Number of redundant instructions removed");
|
|
|
|
namespace {
|
|
struct InstSimplifier : public FunctionPass {
|
|
static char ID; // Pass identification, replacement for typeid
|
|
InstSimplifier() : FunctionPass(ID) {
|
|
initializeInstSimplifierPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.setPreservesCFG();
|
|
AU.addRequired<AssumptionCacheTracker>();
|
|
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
|
}
|
|
|
|
/// runOnFunction - Remove instructions that simplify.
|
|
bool runOnFunction(Function &F) override {
|
|
const DominatorTreeWrapperPass *DTWP =
|
|
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
|
const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
|
|
const DataLayout &DL = F.getParent()->getDataLayout();
|
|
const TargetLibraryInfo *TLI =
|
|
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
|
AssumptionCache *AC =
|
|
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
|
SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
|
|
bool Changed = false;
|
|
|
|
do {
|
|
for (BasicBlock *BB : depth_first(&F.getEntryBlock()))
|
|
// Here be subtlety: the iterator must be incremented before the loop
|
|
// body (not sure why), so a range-for loop won't work here.
|
|
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
|
|
Instruction *I = BI++;
|
|
// The first time through the loop ToSimplify is empty and we try to
|
|
// simplify all instructions. On later iterations ToSimplify is not
|
|
// empty and we only bother simplifying instructions that are in it.
|
|
if (!ToSimplify->empty() && !ToSimplify->count(I))
|
|
continue;
|
|
// Don't waste time simplifying unused instructions.
|
|
if (!I->use_empty())
|
|
if (Value *V = SimplifyInstruction(I, &DL, TLI, DT, AC)) {
|
|
// Mark all uses for resimplification next time round the loop.
|
|
for (User *U : I->users())
|
|
Next->insert(cast<Instruction>(U));
|
|
I->replaceAllUsesWith(V);
|
|
++NumSimplified;
|
|
Changed = true;
|
|
}
|
|
bool res = RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
|
|
if (res) {
|
|
// RecursivelyDeleteTriviallyDeadInstruction can remove
|
|
// more than one instruction, so simply incrementing the
|
|
// iterator does not work. When instructions get deleted
|
|
// re-iterate instead.
|
|
BI = BB->begin(); BE = BB->end();
|
|
Changed |= res;
|
|
}
|
|
}
|
|
|
|
// Place the list of instructions to simplify on the next loop iteration
|
|
// into ToSimplify.
|
|
std::swap(ToSimplify, Next);
|
|
Next->clear();
|
|
} while (!ToSimplify->empty());
|
|
|
|
return Changed;
|
|
}
|
|
};
|
|
}
|
|
|
|
char InstSimplifier::ID = 0;
|
|
INITIALIZE_PASS_BEGIN(InstSimplifier, "instsimplify",
|
|
"Remove redundant instructions", false, false)
|
|
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
|
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
|
INITIALIZE_PASS_END(InstSimplifier, "instsimplify",
|
|
"Remove redundant instructions", false, false)
|
|
char &llvm::InstructionSimplifierID = InstSimplifier::ID;
|
|
|
|
// Public interface to the simplify instructions pass.
|
|
FunctionPass *llvm::createInstructionSimplifierPass() {
|
|
return new InstSimplifier();
|
|
}
|