mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-13 23:18:51 +00:00
GlobalISel: use multi-dimensional arrays for legalize actions.
Instead of putting all possible requests into a single table, we can perform the extremely dense lookup based on opcode and type-index in constant time using multi-dimensional array-like things. This roughly halves the time spent doing legalization, which was dominated by queries against the Actions table. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280011 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0d977a1eb5
commit
7c20af79ca
@ -17,6 +17,7 @@
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/CodeGen/LowLevelType.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@ -44,21 +45,6 @@ struct InstrAspect {
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct DenseMapInfo<InstrAspect> {
|
||||
static inline InstrAspect getEmptyKey() { return {-1u, 0, LLT{}}; }
|
||||
|
||||
static inline InstrAspect getTombstoneKey() { return {-2u, 0, LLT{}}; }
|
||||
|
||||
static unsigned getHashValue(const InstrAspect &Val) {
|
||||
return DenseMapInfo<std::pair<uint64_t, LLT>>::getHashValue(
|
||||
{(uint64_t)Val.Opcode << 32 | Val.Idx, Val.Type});
|
||||
}
|
||||
|
||||
static bool isEqual(const InstrAspect &LHS, const InstrAspect &RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
class MachineLegalizer {
|
||||
public:
|
||||
enum LegalizeAction : std::uint8_t {
|
||||
@ -103,6 +89,9 @@ public:
|
||||
/// This operation is completely unsupported on the target. A programming
|
||||
/// error has occurred.
|
||||
Unsupported,
|
||||
|
||||
/// Sentinel value for when no action was found in the specified table.
|
||||
NotFound,
|
||||
};
|
||||
|
||||
MachineLegalizer();
|
||||
@ -116,7 +105,10 @@ public:
|
||||
/// representation.
|
||||
void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
|
||||
TablesInitialized = false;
|
||||
Actions[Aspect] = Action;
|
||||
unsigned Opcode = Aspect.Opcode - FirstOp;
|
||||
if (Actions[Opcode].size() <= Aspect.Idx)
|
||||
Actions[Opcode].resize(Aspect.Idx + 1);
|
||||
Actions[Aspect.Opcode - FirstOp][Aspect.Idx][Aspect.Type] = Action;
|
||||
}
|
||||
|
||||
/// If an operation on a given vector type (say <M x iN>) isn't explicitly
|
||||
@ -152,11 +144,12 @@ public:
|
||||
LLT findLegalType(const InstrAspect &Aspect,
|
||||
std::function<LLT(LLT)> NextType) const {
|
||||
LegalizeAction Action;
|
||||
const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
|
||||
LLT Ty = Aspect.Type;
|
||||
do {
|
||||
Ty = NextType(Ty);
|
||||
auto ActionIt = Actions.find({Aspect.Opcode, Aspect.Idx, Ty});
|
||||
if (ActionIt == Actions.end())
|
||||
auto ActionIt = Map.find(Ty);
|
||||
if (ActionIt == Map.end())
|
||||
Action = DefaultActions.find(Aspect.Opcode)->second;
|
||||
else
|
||||
Action = ActionIt->second;
|
||||
@ -173,13 +166,32 @@ public:
|
||||
return std::make_pair(Action, findLegalType(Aspect, Action));
|
||||
}
|
||||
|
||||
/// Find the specified \p Aspect in the primary (explicitly set) Actions
|
||||
/// table. Returns either the action the target requested or NotFound if there
|
||||
/// was no setAction call.
|
||||
LegalizeAction findInActions(const InstrAspect &Aspect) const {
|
||||
if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
|
||||
return NotFound;
|
||||
if (Aspect.Idx >= Actions[Aspect.Opcode - FirstOp].size())
|
||||
return NotFound;
|
||||
const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
|
||||
auto ActionIt = Map.find(Aspect.Type);
|
||||
if (ActionIt == Map.end())
|
||||
return NotFound;
|
||||
|
||||
return ActionIt->second;
|
||||
}
|
||||
|
||||
bool isLegal(const MachineInstr &MI) const;
|
||||
|
||||
private:
|
||||
typedef DenseMap<InstrAspect, LegalizeAction> ActionMap;
|
||||
static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
|
||||
static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
|
||||
|
||||
typedef DenseMap<LLT, LegalizeAction> TypeMap;
|
||||
typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap;
|
||||
|
||||
ActionMap Actions;
|
||||
SmallVector<TypeMap, 1> Actions[LastOp - FirstOp + 1];
|
||||
SIVActionMap ScalarInVectorActions;
|
||||
DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts;
|
||||
DenseMap<unsigned, LegalizeAction> DefaultActions;
|
||||
|
@ -17,9 +17,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
using namespace llvm;
|
||||
@ -39,14 +39,18 @@ MachineLegalizer::MachineLegalizer() : TablesInitialized(false) {
|
||||
}
|
||||
|
||||
void MachineLegalizer::computeTables() {
|
||||
for (auto &Op : Actions) {
|
||||
LLT Ty = Op.first.Type;
|
||||
if (!Ty.isVector())
|
||||
continue;
|
||||
for (unsigned Opcode = 0; Opcode <= LastOp - FirstOp; ++Opcode) {
|
||||
for (unsigned Idx = 0; Idx != Actions[Opcode].size(); ++Idx) {
|
||||
for (auto &Action : Actions[Opcode][Idx]) {
|
||||
LLT Ty = Action.first;
|
||||
if (!Ty.isVector())
|
||||
continue;
|
||||
|
||||
auto &Entry = MaxLegalVectorElts[std::make_pair(Op.first.Opcode,
|
||||
Ty.getElementType())];
|
||||
Entry = std::max(Entry, Ty.getNumElements());
|
||||
auto &Entry = MaxLegalVectorElts[std::make_pair(Opcode + FirstOp,
|
||||
Ty.getElementType())];
|
||||
Entry = std::max(Entry, Ty.getNumElements());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TablesInitialized = true;
|
||||
@ -68,9 +72,9 @@ MachineLegalizer::getAction(const InstrAspect &Aspect) const {
|
||||
Aspect.Opcode == TargetOpcode::G_EXTRACT)
|
||||
return std::make_pair(Legal, Aspect.Type);
|
||||
|
||||
auto ActionIt = Actions.find(Aspect);
|
||||
if (ActionIt != Actions.end())
|
||||
return findLegalAction(Aspect, ActionIt->second);
|
||||
LegalizeAction Action = findInActions(Aspect);
|
||||
if (Action != NotFound)
|
||||
return findLegalAction(Aspect, Action);
|
||||
|
||||
unsigned Opcode = Aspect.Opcode;
|
||||
LLT Ty = Aspect.Type;
|
||||
|
@ -21,6 +21,7 @@ using llvm::MachineLegalizer::LegalizeAction::MoreElements;
|
||||
using llvm::MachineLegalizer::LegalizeAction::Libcall;
|
||||
using llvm::MachineLegalizer::LegalizeAction::Custom;
|
||||
using llvm::MachineLegalizer::LegalizeAction::Unsupported;
|
||||
using llvm::MachineLegalizer::LegalizeAction::NotFound;
|
||||
|
||||
// Define a couple of pretty printers to help debugging when things go wrong.
|
||||
namespace llvm {
|
||||
@ -36,6 +37,7 @@ operator<<(std::ostream &OS, const llvm::MachineLegalizer::LegalizeAction Act) {
|
||||
case Libcall: OS << "Libcall"; break;
|
||||
case Custom: OS << "Custom"; break;
|
||||
case Unsupported: OS << "Unsupported"; break;
|
||||
case NotFound: OS << "NotFound";
|
||||
}
|
||||
return OS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user