#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/Target/TargetOpcodes.h"
#include <cstdint>
#include <functional>
}
};
-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 {
/// 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();
/// 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
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;
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;
//
//===----------------------------------------------------------------------===//
+#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;
}
void MachineLegalizer::computeTables() {
- for (auto &Op : Actions) {
- LLT Ty = Op.first.Type;
- if (!Ty.isVector())
- continue;
-
- auto &Entry = MaxLegalVectorElts[std::make_pair(Op.first.Opcode,
- Ty.getElementType())];
- Entry = std::max(Entry, Ty.getNumElements());
+ 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(Opcode + FirstOp,
+ Ty.getElementType())];
+ Entry = std::max(Entry, Ty.getNumElements());
+ }
+ }
}
TablesInitialized = true;
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;