mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
This is exciting as this is a much more involved port. This is a complex, existing transformation pass. All of the core logic is shared between both old and new pass managers. Only the access to the analyses is separate because the actual techniques are separate. This also uses a bunch of different and interesting analyses and is the first time where we need to use an analysis across an IR layer. This also paves the way to expose instcombine utility functions. I've got a static function that implements the core pass logic over a function which might be mildly interesting, but more interesting is likely exposing a routine which just uses instructions *already in* the worklist and combines until empty. I've switched one of my favorite instcombine tests to run with both as well to make sure this keeps working. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226987 91177308-0d34-0410-b5e6-96231b3b80d8
117 lines
3.6 KiB
C++
117 lines
3.6 KiB
C++
//===- InstCombineWorklist.h - Worklist for InstCombine pass ----*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINEWORKLIST_H
|
|
#define LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINEWORKLIST_H
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/IR/Instruction.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#define DEBUG_TYPE "instcombine"
|
|
|
|
namespace llvm {
|
|
|
|
/// InstCombineWorklist - This is the worklist management logic for
|
|
/// InstCombine.
|
|
class LLVM_LIBRARY_VISIBILITY InstCombineWorklist {
|
|
SmallVector<Instruction*, 256> Worklist;
|
|
DenseMap<Instruction*, unsigned> WorklistMap;
|
|
|
|
void operator=(const InstCombineWorklist&RHS) LLVM_DELETED_FUNCTION;
|
|
InstCombineWorklist(const InstCombineWorklist&) LLVM_DELETED_FUNCTION;
|
|
public:
|
|
InstCombineWorklist() {}
|
|
|
|
InstCombineWorklist(InstCombineWorklist &&Arg)
|
|
: Worklist(std::move(Arg.Worklist)),
|
|
WorklistMap(std::move(Arg.WorklistMap)) {}
|
|
InstCombineWorklist &operator=(InstCombineWorklist &&RHS) {
|
|
Worklist = std::move(RHS.Worklist);
|
|
WorklistMap = std::move(RHS.WorklistMap);
|
|
return *this;
|
|
}
|
|
|
|
bool isEmpty() const { return Worklist.empty(); }
|
|
|
|
/// Add - Add the specified instruction to the worklist if it isn't already
|
|
/// in it.
|
|
void Add(Instruction *I) {
|
|
if (WorklistMap.insert(std::make_pair(I, Worklist.size())).second) {
|
|
DEBUG(dbgs() << "IC: ADD: " << *I << '\n');
|
|
Worklist.push_back(I);
|
|
}
|
|
}
|
|
|
|
void AddValue(Value *V) {
|
|
if (Instruction *I = dyn_cast<Instruction>(V))
|
|
Add(I);
|
|
}
|
|
|
|
/// AddInitialGroup - Add the specified batch of stuff in reverse order.
|
|
/// which should only be done when the worklist is empty and when the group
|
|
/// has no duplicates.
|
|
void AddInitialGroup(Instruction *const *List, unsigned NumEntries) {
|
|
assert(Worklist.empty() && "Worklist must be empty to add initial group");
|
|
Worklist.reserve(NumEntries+16);
|
|
WorklistMap.resize(NumEntries);
|
|
DEBUG(dbgs() << "IC: ADDING: " << NumEntries << " instrs to worklist\n");
|
|
for (unsigned Idx = 0; NumEntries; --NumEntries) {
|
|
Instruction *I = List[NumEntries-1];
|
|
WorklistMap.insert(std::make_pair(I, Idx++));
|
|
Worklist.push_back(I);
|
|
}
|
|
}
|
|
|
|
// Remove - remove I from the worklist if it exists.
|
|
void Remove(Instruction *I) {
|
|
DenseMap<Instruction*, unsigned>::iterator It = WorklistMap.find(I);
|
|
if (It == WorklistMap.end()) return; // Not in worklist.
|
|
|
|
// Don't bother moving everything down, just null out the slot.
|
|
Worklist[It->second] = nullptr;
|
|
|
|
WorklistMap.erase(It);
|
|
}
|
|
|
|
Instruction *RemoveOne() {
|
|
Instruction *I = Worklist.pop_back_val();
|
|
WorklistMap.erase(I);
|
|
return I;
|
|
}
|
|
|
|
/// AddUsersToWorkList - When an instruction is simplified, add all users of
|
|
/// the instruction to the work lists because they might get more simplified
|
|
/// now.
|
|
///
|
|
void AddUsersToWorkList(Instruction &I) {
|
|
for (User *U : I.users())
|
|
Add(cast<Instruction>(U));
|
|
}
|
|
|
|
|
|
/// Zap - check that the worklist is empty and nuke the backing store for
|
|
/// the map if it is large.
|
|
void Zap() {
|
|
assert(WorklistMap.empty() && "Worklist empty, but map not?");
|
|
|
|
// Do an explicit clear, this shrinks the map if needed.
|
|
WorklistMap.clear();
|
|
}
|
|
};
|
|
|
|
} // end namespace llvm.
|
|
|
|
#undef DEBUG_TYPE
|
|
|
|
#endif
|