forked from OSchip/llvm-project
[NFC][Regalloc] Factor types that would be used by the eviction advisor
This is in prepartion of pulling the eviction decision-making into an analysis pass, which would then allow swapping that decision making process. RFC: https://lists.llvm.org/pipermail/llvm-dev/2021-November/153639.html Differential Revision: https://reviews.llvm.org/D113929
This commit is contained in:
parent
fee52fe0ad
commit
19e6b730ce
|
@ -0,0 +1,90 @@
|
|||
//===- RegAllocEvictionAdvisor.h - Interference resolution ------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
|
||||
#define LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
|
||||
|
||||
#include "AllocationOrder.h"
|
||||
#include "llvm/ADT/IndexedMap.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/CodeGen/LiveInterval.h"
|
||||
#include "llvm/CodeGen/LiveIntervals.h"
|
||||
#include "llvm/CodeGen/LiveRegMatrix.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Register.h"
|
||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
using SmallVirtRegSet = SmallSet<Register, 16>;
|
||||
|
||||
// Live ranges pass through a number of stages as we try to allocate them.
|
||||
// Some of the stages may also create new live ranges:
|
||||
//
|
||||
// - Region splitting.
|
||||
// - Per-block splitting.
|
||||
// - Local splitting.
|
||||
// - Spilling.
|
||||
//
|
||||
// Ranges produced by one of the stages skip the previous stages when they are
|
||||
// dequeued. This improves performance because we can skip interference checks
|
||||
// that are unlikely to give any results. It also guarantees that the live
|
||||
// range splitting algorithm terminates, something that is otherwise hard to
|
||||
// ensure.
|
||||
enum LiveRangeStage {
|
||||
/// Newly created live range that has never been queued.
|
||||
RS_New,
|
||||
|
||||
/// Only attempt assignment and eviction. Then requeue as RS_Split.
|
||||
RS_Assign,
|
||||
|
||||
/// Attempt live range splitting if assignment is impossible.
|
||||
RS_Split,
|
||||
|
||||
/// Attempt more aggressive live range splitting that is guaranteed to make
|
||||
/// progress. This is used for split products that may not be making
|
||||
/// progress.
|
||||
RS_Split2,
|
||||
|
||||
/// Live range will be spilled. No more splitting will be attempted.
|
||||
RS_Spill,
|
||||
|
||||
/// Live range is in memory. Because of other evictions, it might get moved
|
||||
/// in a register in the end.
|
||||
RS_Memory,
|
||||
|
||||
/// There is nothing more we can do to this live range. Abort compilation
|
||||
/// if it can't be assigned.
|
||||
RS_Done
|
||||
};
|
||||
|
||||
/// Cost of evicting interference - used by default advisor, and the eviction
|
||||
/// chain heuristic in RegAllocGreedy.
|
||||
// FIXME: this can be probably made an implementation detail of the default
|
||||
// advisor, if the eviction chain logic can be refactored.
|
||||
struct EvictionCost {
|
||||
unsigned BrokenHints = 0; ///< Total number of broken hints.
|
||||
float MaxWeight = 0; ///< Maximum spill weight evicted.
|
||||
|
||||
EvictionCost() = default;
|
||||
|
||||
bool isMax() const { return BrokenHints == ~0u; }
|
||||
|
||||
void setMax() { BrokenHints = ~0u; }
|
||||
|
||||
void setBrokenHints(unsigned NHints) { BrokenHints = NHints; }
|
||||
|
||||
bool operator<(const EvictionCost &O) const {
|
||||
return std::tie(BrokenHints, MaxWeight) <
|
||||
std::tie(O.BrokenHints, O.MaxWeight);
|
||||
}
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_CODEGEN_REGALLOCEVICTIONADVISOR_H
|
|
@ -15,6 +15,7 @@
|
|||
#include "InterferenceCache.h"
|
||||
#include "LiveDebugVariables.h"
|
||||
#include "RegAllocBase.h"
|
||||
#include "RegAllocEvictionAdvisor.h"
|
||||
#include "SpillPlacement.h"
|
||||
#include "SplitKit.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
@ -57,6 +58,7 @@
|
|||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include "llvm/CodeGen/VirtRegMap.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
|
@ -69,7 +71,6 @@
|
|||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
@ -148,7 +149,6 @@ class RAGreedy : public MachineFunctionPass,
|
|||
// Convenient shortcuts.
|
||||
using PQueue = std::priority_queue<std::pair<unsigned, unsigned>>;
|
||||
using SmallLISet = SmallPtrSet<LiveInterval *, 4>;
|
||||
using SmallVirtRegSet = SmallSet<Register, 16>;
|
||||
|
||||
// context
|
||||
MachineFunction *MF;
|
||||
|
@ -175,47 +175,6 @@ class RAGreedy : public MachineFunctionPass,
|
|||
unsigned NextCascade;
|
||||
std::unique_ptr<VirtRegAuxInfo> VRAI;
|
||||
|
||||
// Live ranges pass through a number of stages as we try to allocate them.
|
||||
// Some of the stages may also create new live ranges:
|
||||
//
|
||||
// - Region splitting.
|
||||
// - Per-block splitting.
|
||||
// - Local splitting.
|
||||
// - Spilling.
|
||||
//
|
||||
// Ranges produced by one of the stages skip the previous stages when they are
|
||||
// dequeued. This improves performance because we can skip interference checks
|
||||
// that are unlikely to give any results. It also guarantees that the live
|
||||
// range splitting algorithm terminates, something that is otherwise hard to
|
||||
// ensure.
|
||||
enum LiveRangeStage {
|
||||
/// Newly created live range that has never been queued.
|
||||
RS_New,
|
||||
|
||||
/// Only attempt assignment and eviction. Then requeue as RS_Split.
|
||||
RS_Assign,
|
||||
|
||||
/// Attempt live range splitting if assignment is impossible.
|
||||
RS_Split,
|
||||
|
||||
/// Attempt more aggressive live range splitting that is guaranteed to make
|
||||
/// progress. This is used for split products that may not be making
|
||||
/// progress.
|
||||
RS_Split2,
|
||||
|
||||
/// Live range will be spilled. No more splitting will be attempted.
|
||||
RS_Spill,
|
||||
|
||||
|
||||
/// Live range is in memory. Because of other evictions, it might get moved
|
||||
/// in a register in the end.
|
||||
RS_Memory,
|
||||
|
||||
/// There is nothing more we can do to this live range. Abort compilation
|
||||
/// if it can't be assigned.
|
||||
RS_Done
|
||||
};
|
||||
|
||||
// Enum CutOffStage to keep a track whether the register allocation failed
|
||||
// because of the cutoffs encountered in last chance recoloring.
|
||||
// Note: This is used as bitmask. New value should be next power of 2.
|
||||
|
@ -267,25 +226,6 @@ class RAGreedy : public MachineFunctionPass,
|
|||
}
|
||||
}
|
||||
|
||||
/// Cost of evicting interference.
|
||||
struct EvictionCost {
|
||||
unsigned BrokenHints = 0; ///< Total number of broken hints.
|
||||
float MaxWeight = 0; ///< Maximum spill weight evicted.
|
||||
|
||||
EvictionCost() = default;
|
||||
|
||||
bool isMax() const { return BrokenHints == ~0u; }
|
||||
|
||||
void setMax() { BrokenHints = ~0u; }
|
||||
|
||||
void setBrokenHints(unsigned NHints) { BrokenHints = NHints; }
|
||||
|
||||
bool operator<(const EvictionCost &O) const {
|
||||
return std::tie(BrokenHints, MaxWeight) <
|
||||
std::tie(O.BrokenHints, O.MaxWeight);
|
||||
}
|
||||
};
|
||||
|
||||
/// EvictionTrack - Keeps track of past evictions in order to optimize region
|
||||
/// split decision.
|
||||
class EvictionTrack {
|
||||
|
|
Loading…
Reference in New Issue