mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
8bfe50871f
This pass precomputes CFG block frequency information that can be used by the register allocator to find optimal spill code placement. Given an interference pattern, placeSpills() will compute which basic blocks should have the current variable enter or exit in a register, and which blocks prefer the stack. The algorithm is ready to consume block frequencies from profiling data, but for now it gets by with the static estimates used for spill weights. This is a work in progress and still not hooked up to RegAllocGreedy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122938 91177308-0d34-0410-b5e6-96231b3b80d8
106 lines
4.1 KiB
C++
106 lines
4.1 KiB
C++
//===-- SpillPlacement.h - Optimal Spill Code Placement --------*- C++ -*--===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This analysis computes the optimal spill code placement between basic blocks.
|
|
//
|
|
// The runOnMachineFunction() method only precomputes some profiling information
|
|
// about the CFG. The real work is done by placeSpills() which is called by the
|
|
// register allocator.
|
|
//
|
|
// Given a variable that is live across multiple basic blocks, and given
|
|
// constraints on the basic blocks where the variable is live, determine which
|
|
// edge bundles should have the variable in a register and which edge bundles
|
|
// should have the variable in a stack slot.
|
|
//
|
|
// The returned bit vector can be used to place optimal spill code at basic
|
|
// block entries and exits. Spill code placement inside a basic block is not
|
|
// considered.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_SPILLPLACEMENT_H
|
|
#define LLVM_CODEGEN_SPILLPLACEMENT_H
|
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
|
|
namespace llvm {
|
|
|
|
class BitVector;
|
|
class EdgeBundles;
|
|
class MachineBasicBlock;
|
|
class MachineLoopInfo;
|
|
template <typename> class SmallVectorImpl;
|
|
|
|
class SpillPlacement : public MachineFunctionPass {
|
|
struct Node;
|
|
const MachineFunction *MF;
|
|
const EdgeBundles *bundles;
|
|
const MachineLoopInfo *loops;
|
|
Node *nodes;
|
|
|
|
// Nodes that are active in the current computation. Owned by the placeSpills
|
|
// caller.
|
|
BitVector *ActiveNodes;
|
|
|
|
public:
|
|
static char ID; // Pass identification, replacement for typeid.
|
|
|
|
SpillPlacement() : MachineFunctionPass(ID), nodes(0) {}
|
|
~SpillPlacement() { releaseMemory(); }
|
|
|
|
/// BorderConstraint - A basic block has separate constraints for entry and
|
|
/// exit.
|
|
enum BorderConstraint {
|
|
DontCare, ///< Block doesn't care / variable not live.
|
|
PrefReg, ///< Block entry/exit prefers a register.
|
|
PrefSpill, ///< Block entry/exit prefers a stack slot.
|
|
MustSpill ///< A register is impossible, variable must be spilled.
|
|
};
|
|
|
|
/// BlockConstraint - Entry and exit constraints for a basic block.
|
|
struct BlockConstraint {
|
|
unsigned Number; ///< Basic block number (from MBB::getNumber()).
|
|
BorderConstraint Entry : 8; ///< Constraint on block entry.
|
|
BorderConstraint Exit : 8; ///< Constraint on block exit.
|
|
};
|
|
|
|
/// placeSpills - Compute the optimal spill code placement given the
|
|
/// constraints. No MustSpill constraints will be violated, and the smallest
|
|
/// possible number of PrefX constraints will be violated, weighted by
|
|
/// expected execution frequencies.
|
|
/// @param LiveBlocks Constraints for blocks that have the variable live in or
|
|
/// live out. DontCare/DontCare means the variable is live
|
|
/// through the block. DontCare/X means the variable is live
|
|
/// out, but not live in.
|
|
/// @param RegBundles Bit vector to receive the edge bundles where the
|
|
/// variable should be kept in a register. Each bit
|
|
/// corresponds to an edge bundle, a set bit means the
|
|
/// variable should be kept in a register through the
|
|
/// bundle. A clear bit means the variable should be
|
|
/// spilled.
|
|
/// @return True if a perfect solution was found, allowing the variable to be
|
|
/// in a register through all relevant bundles.
|
|
bool placeSpills(const SmallVectorImpl<BlockConstraint> &LiveBlocks,
|
|
BitVector &RegBundles);
|
|
|
|
private:
|
|
virtual bool runOnMachineFunction(MachineFunction&);
|
|
virtual void getAnalysisUsage(AnalysisUsage&) const;
|
|
virtual void releaseMemory();
|
|
|
|
void activate(unsigned);
|
|
float getBlockFrequency(const MachineBasicBlock*);
|
|
void prepareNodes(const SmallVectorImpl<BlockConstraint>&);
|
|
void iterate(const SmallVectorImpl<unsigned>&);
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|