mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	This requires a number of steps. 1) Move value_use_iterator into the Value class as an implementation detail 2) Change it to actually be a *Use* iterator rather than a *User* iterator. 3) Add an adaptor which is a User iterator that always looks through the Use to the User. 4) Wrap these in Value::use_iterator and Value::user_iterator typedefs. 5) Add the range adaptors as Value::uses() and Value::users(). 6) Update *all* of the callers to correctly distinguish between whether they wanted a use_iterator (and to explicitly dig out the User when needed), or a user_iterator which makes the Use itself totally opaque. Because #6 requires churning essentially everything that walked the Use-Def chains, I went ahead and added all of the range adaptors and switched them to range-based loops where appropriate. Also because the renaming requires at least churning every line of code, it didn't make any sense to split these up into multiple commits -- all of which would touch all of the same lies of code. The result is still not quite optimal. The Value::use_iterator is a nice regular iterator, but Value::user_iterator is an iterator over User*s rather than over the User objects themselves. As a consequence, it fits a bit awkwardly into the range-based world and it has the weird extra-dereferencing 'operator->' that so many of our iterators have. I think this could be fixed by providing something which transforms a range of T&s into a range of T*s, but that *can* be separated into another patch, and it isn't yet 100% clear whether this is the right move. However, this change gets us most of the benefit and cleans up a substantial amount of code around Use and User. =] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203364 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			103 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			4.1 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.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#define DEBUG_TYPE "instsimplify"
 | 
						|
#include "llvm/Transforms/Scalar.h"
 | 
						|
#include "llvm/ADT/DepthFirstIterator.h"
 | 
						|
#include "llvm/ADT/SmallPtrSet.h"
 | 
						|
#include "llvm/ADT/Statistic.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/Target/TargetLibraryInfo.h"
 | 
						|
#include "llvm/Transforms/Utils/Local.h"
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
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<TargetLibraryInfo>();
 | 
						|
    }
 | 
						|
 | 
						|
    /// runOnFunction - Remove instructions that simplify.
 | 
						|
    bool runOnFunction(Function &F) override {
 | 
						|
      const DominatorTreeWrapperPass *DTWP =
 | 
						|
          getAnalysisIfAvailable<DominatorTreeWrapperPass>();
 | 
						|
      const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : 0;
 | 
						|
      DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
 | 
						|
      const DataLayout *DL = DLP ? &DLP->getDataLayout() : 0;
 | 
						|
      const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
 | 
						|
      SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
 | 
						|
      bool Changed = false;
 | 
						|
 | 
						|
      do {
 | 
						|
        for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
 | 
						|
             DE = df_end(&F.getEntryBlock()); DI != DE; ++DI)
 | 
						|
          for (BasicBlock::iterator BI = DI->begin(), BE = DI->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)) {
 | 
						|
                // 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;
 | 
						|
              }
 | 
						|
            Changed |= RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
 | 
						|
          }
 | 
						|
 | 
						|
        // 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(TargetLibraryInfo)
 | 
						|
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();
 | 
						|
}
 |