forked from OSchip/llvm-project
91 lines
2.9 KiB
C++
91 lines
2.9 KiB
C++
//===- 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
|