projects
/
oota-llvm.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
R600: Add ISA documents to the CompilerWriterInfo page
[oota-llvm.git]
/
utils
/
TableGen
/
FastISelEmitter.cpp
diff --git
a/utils/TableGen/FastISelEmitter.cpp
b/utils/TableGen/FastISelEmitter.cpp
index f946ac73cac24d5b20144250b0941c2747cd5aa0..ce7f8c81632a7a919b6dd50e604699312dd7c620 100644
(file)
--- a/
utils/TableGen/FastISelEmitter.cpp
+++ b/
utils/TableGen/FastISelEmitter.cpp
@@
-17,29
+17,31
@@
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
-#include "FastISelEmitter.h"
-#include "Error.h"
-#include "Record.h"
+#include "CodeGenDAGPatterns.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
using namespace llvm;
using namespace llvm;
-namespace {
/// InstructionMemo - This class holds additional information about an
/// instruction needed to emit code for it.
///
/// InstructionMemo - This class holds additional information about an
/// instruction needed to emit code for it.
///
+namespace {
struct InstructionMemo {
std::string Name;
const CodeGenRegisterClass *RC;
std::string SubRegNo;
std::vector<std::string>* PhysRegs;
};
struct InstructionMemo {
std::string Name;
const CodeGenRegisterClass *RC;
std::string SubRegNo;
std::vector<std::string>* PhysRegs;
};
-
+} // End anonymous namespace
+
/// ImmPredicateSet - This uniques predicates (represented as a string) and
/// gives them unique (small) integer ID's that start at 0.
/// ImmPredicateSet - This uniques predicates (represented as a string) and
/// gives them unique (small) integer ID's that start at 0.
+namespace {
class ImmPredicateSet {
DenseMap<TreePattern *, unsigned> ImmIDs;
std::vector<TreePredicateFn> PredsByName;
class ImmPredicateSet {
DenseMap<TreePattern *, unsigned> ImmIDs;
std::vector<TreePredicateFn> PredsByName;
@@
-64,10
+66,12
@@
public:
iterator end() const { return PredsByName.end(); }
};
iterator end() const { return PredsByName.end(); }
};
+} // End anonymous namespace
/// OperandsSignature - This class holds a description of a list of operand
/// types. It has utility methods for emitting text based on the operands.
///
/// OperandsSignature - This class holds a description of a list of operand
/// types. It has utility methods for emitting text based on the operands.
///
+namespace {
struct OperandsSignature {
class OpKind {
enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 };
struct OperandsSignature {
class OpKind {
enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 };
@@
-169,7
+173,8
@@
struct OperandsSignature {
///
bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target,
MVT::SimpleValueType VT,
///
bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target,
MVT::SimpleValueType VT,
- ImmPredicateSet &ImmediatePredicates) {
+ ImmPredicateSet &ImmediatePredicates,
+ const CodeGenRegisterClass *OrigDstRC) {
if (InstPatNode->isLeaf())
return false;
if (InstPatNode->isLeaf())
return false;
@@
-241,18
+246,22
@@
struct OperandsSignature {
if (Op->getType(0) != VT)
return false;
if (Op->getType(0) != VT)
return false;
- DefInit *OpDI = dyn
amic_cast<DefInit*
>(Op->getLeafValue());
+ DefInit *OpDI = dyn
_cast<DefInit
>(Op->getLeafValue());
if (!OpDI)
return false;
Record *OpLeafRec = OpDI->getDef();
// For now, the only other thing we accept is register operands.
const CodeGenRegisterClass *RC = 0;
if (!OpDI)
return false;
Record *OpLeafRec = OpDI->getDef();
// For now, the only other thing we accept is register operands.
const CodeGenRegisterClass *RC = 0;
+ if (OpLeafRec->isSubClassOf("RegisterOperand"))
+ OpLeafRec = OpLeafRec->getValueAsDef("RegClass");
if (OpLeafRec->isSubClassOf("RegisterClass"))
RC = &Target.getRegisterClass(OpLeafRec);
else if (OpLeafRec->isSubClassOf("Register"))
RC = Target.getRegBank().getRegClassForRegister(OpLeafRec);
if (OpLeafRec->isSubClassOf("RegisterClass"))
RC = &Target.getRegisterClass(OpLeafRec);
else if (OpLeafRec->isSubClassOf("Register"))
RC = Target.getRegBank().getRegClassForRegister(OpLeafRec);
- else
+ else if (OpLeafRec->isSubClassOf("ValueType")) {
+ RC = OrigDstRC;
+ } else
return false;
// For now, this needs to be a register class of some sort.
return false;
// For now, this needs to be a register class of some sort.
@@
-278,7
+287,7
@@
struct OperandsSignature {
} else if (Operands[i].isImm()) {
OS << "uint64_t imm" << i;
} else if (Operands[i].isFP()) {
} else if (Operands[i].isImm()) {
OS << "uint64_t imm" << i;
} else if (Operands[i].isFP()) {
- OS << "ConstantFP *f" << i;
+ OS << "
const
ConstantFP *f" << i;
} else {
llvm_unreachable("Unknown operand kind!");
}
} else {
llvm_unreachable("Unknown operand kind!");
}
@@
-351,7
+360,9
@@
struct OperandsSignature {
Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
}
};
Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
}
};
+} // End anonymous namespace
+namespace {
class FastISelMap {
typedef std::map<std::string, InstructionMemo> PredMap;
typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
class FastISelMap {
typedef std::map<std::string, InstructionMemo> PredMap;
typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
@@
-374,8
+385,7
@@
public:
void printImmediatePredicates(raw_ostream &OS);
void printFunctionDefinitions(raw_ostream &OS);
};
void printImmediatePredicates(raw_ostream &OS);
void printFunctionDefinitions(raw_ostream &OS);
};
-
-}
+} // End anonymous namespace
static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
return CGP.getSDNodeInfo(Op).getEnumName();
static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
return CGP.getSDNodeInfo(Op).getEnumName();
@@
-399,13
+409,12
@@
static std::string PhyRegForNode(TreePatternNode *Op,
if (!Op->isLeaf())
return PhysReg;
if (!Op->isLeaf())
return PhysReg;
- DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue());
- Record *OpLeafRec = OpDI->getDef();
+ Record *OpLeafRec = cast<DefInit>(Op->getLeafValue())->getDef();
if (!OpLeafRec->isSubClassOf("Register"))
return PhysReg;
if (!OpLeafRec->isSubClassOf("Register"))
return PhysReg;
- PhysReg +=
static_cast<StringInit*>(OpLeafRec->getValue( \
-
"Namespace")->getValue())
->getValue();
+ PhysReg +=
cast<StringInit>(OpLeafRec->getValue("Namespace")->getValue())
+
->getValue();
PhysReg += "::";
PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName();
return PhysReg;
PhysReg += "::";
PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName();
return PhysReg;
@@
-454,6
+463,8
@@
void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
std::string SubRegNo;
if (Op->getName() != "EXTRACT_SUBREG") {
Record *Op0Rec = II.Operands[0].Rec;
std::string SubRegNo;
if (Op->getName() != "EXTRACT_SUBREG") {
Record *Op0Rec = II.Operands[0].Rec;
+ if (Op0Rec->isSubClassOf("RegisterOperand"))
+ Op0Rec = Op0Rec->getValueAsDef("RegClass");
if (!Op0Rec->isSubClassOf("RegisterClass"))
continue;
DstRC = &Target.getRegisterClass(Op0Rec);
if (!Op0Rec->isSubClassOf("RegisterClass"))
continue;
DstRC = &Target.getRegisterClass(Op0Rec);
@@
-464,7
+475,7
@@
void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
// a bit too complicated for now.
if (!Dst->getChild(1)->isLeaf()) continue;
// a bit too complicated for now.
if (!Dst->getChild(1)->isLeaf()) continue;
- DefInit *SR = dyn
amic_cast<DefInit*
>(Dst->getChild(1)->getLeafValue());
+ DefInit *SR = dyn
_cast<DefInit
>(Dst->getChild(1)->getLeafValue());
if (SR)
SubRegNo = getQualifiedName(SR->getDef());
else
if (SR)
SubRegNo = getQualifiedName(SR->getDef());
else
@@
-495,12
+506,13
@@
void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
// Check all the operands.
OperandsSignature Operands;
// Check all the operands.
OperandsSignature Operands;
- if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates))
+ if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates,
+ DstRC))
continue;
std::vector<std::string>* PhysRegInputs = new std::vector<std::string>();
if (InstPatNode->getOperator()->getName() == "imm" ||
continue;
std::vector<std::string>* PhysRegInputs = new std::vector<std::string>();
if (InstPatNode->getOperator()->getName() == "imm" ||
- InstPatNode->getOperator()->getName() == "fpimm
m
")
+ InstPatNode->getOperator()->getName() == "fpimm")
PhysRegInputs->push_back("");
else {
// Compute the PhysRegs used by the given pattern, and check that
PhysRegInputs->push_back("");
else {
// Compute the PhysRegs used by the given pattern, and check that
@@
-541,7
+553,7
@@
void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
};
if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck))
};
if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck))
-
throw TG
Error(Pattern.getSrcRecord()->getLoc(),
+
PrintFatal
Error(Pattern.getSrcRecord()->getLoc(),
"Duplicate record in FastISel table!");
SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo;
"Duplicate record in FastISel table!");
SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo;
@@
-636,7
+648,7
@@
void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
Operands.PrintManglingSuffix(OS, *Memo.PhysRegs,
ImmediatePredicates, true);
OS << "(" << InstNS << Memo.Name << ", ";
Operands.PrintManglingSuffix(OS, *Memo.PhysRegs,
ImmediatePredicates, true);
OS << "(" << InstNS << Memo.Name << ", ";
- OS <<
InstNS << Memo.RC->getName() << "Register
Class";
+ OS <<
"&" << InstNS << Memo.RC->getName() << "Reg
Class";
if (!Operands.empty())
OS << ", ";
Operands.PrintArguments(OS, *Memo.PhysRegs);
if (!Operands.empty())
OS << ", ";
Operands.PrintArguments(OS, *Memo.PhysRegs);
@@
-728,7
+740,7
@@
void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
Operands.PrintManglingSuffix(OS, *Memo.PhysRegs,
ImmediatePredicates, true);
OS << "(" << InstNS << Memo.Name << ", ";
Operands.PrintManglingSuffix(OS, *Memo.PhysRegs,
ImmediatePredicates, true);
OS << "(" << InstNS << Memo.Name << ", ";
- OS <<
InstNS << Memo.RC->getName() << "Register
Class";
+ OS <<
"&" << InstNS << Memo.RC->getName() << "Reg
Class";
if (!Operands.empty())
OS << ", ";
Operands.PrintArguments(OS, *Memo.PhysRegs);
if (!Operands.empty())
OS << ", ";
Operands.PrintArguments(OS, *Memo.PhysRegs);
@@
-847,23
+859,22
@@
void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
// TODO: SignaturesWithConstantForms should be empty here.
}
// TODO: SignaturesWithConstantForms should be empty here.
}
-void FastISelEmitter::run(raw_ostream &OS) {
+namespace llvm {
+
+void EmitFastISel(RecordKeeper &RK, raw_ostream &OS) {
+ CodeGenDAGPatterns CGP(RK);
const CodeGenTarget &Target = CGP.getTargetInfo();
const CodeGenTarget &Target = CGP.getTargetInfo();
+ emitSourceFileHeader("\"Fast\" Instruction Selector for the " +
+ Target.getName() + " target", OS);
// Determine the target's namespace name.
std::string InstNS = Target.getInstNamespace() + "::";
assert(InstNS.size() > 2 && "Can't determine target-specific namespace!");
// Determine the target's namespace name.
std::string InstNS = Target.getInstNamespace() + "::";
assert(InstNS.size() > 2 && "Can't determine target-specific namespace!");
- EmitSourceFileHeader("\"Fast\" Instruction Selector for the " +
- Target.getName() + " target", OS);
-
FastISelMap F(InstNS);
F.collectPatterns(CGP);
F.printImmediatePredicates(OS);
F.printFunctionDefinitions(OS);
}
FastISelMap F(InstNS);
F.collectPatterns(CGP);
F.printImmediatePredicates(OS);
F.printFunctionDefinitions(OS);
}
-FastISelEmitter::FastISelEmitter(RecordKeeper &R)
- : Records(R), CGP(R) {
-}
-
+} // End llvm namespace