aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-07-21 00:45:20 -0700
committerStephen Hines <srhines@google.com>2014-07-21 00:45:20 -0700
commitc6a4f5e819217e1e12c458aed8e7b122e23a3a58 (patch)
tree81b7dd2bb4370a392f31d332a566c903b5744764 /utils/TableGen
parent19c6fbb3e8aaf74093afa08013134b61fa08f245 (diff)
downloadexternal_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.zip
external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.gz
external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.bz2
Update LLVM for rebase to r212749.
Includes a cherry-pick of: r212948 - fixes a small issue with atomic calls Change-Id: Ib97bd980b59f18142a69506400911a6009d9df18
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/Android.mk1
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp47
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp66
-rw-r--r--utils/TableGen/CMakeLists.txt1
-rw-r--r--utils/TableGen/CTagsEmitter.cpp4
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp8
-rw-r--r--utils/TableGen/CodeGenIntrinsics.h1
-rw-r--r--utils/TableGen/CodeGenRegisters.h2
-rw-r--r--utils/TableGen/CodeGenSchedule.h2
-rw-r--r--utils/TableGen/CodeGenTarget.cpp2
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp56
-rw-r--r--utils/TableGen/SetTheory.cpp323
-rw-r--r--utils/TableGen/SetTheory.h142
-rw-r--r--utils/TableGen/TableGen.cpp2
14 files changed, 143 insertions, 514 deletions
diff --git a/utils/TableGen/Android.mk b/utils/TableGen/Android.mk
index c982168..a743950 100644
--- a/utils/TableGen/Android.mk
+++ b/utils/TableGen/Android.mk
@@ -27,7 +27,6 @@ tablegen_SRC_FILES := \
OptParserEmitter.cpp \
PseudoLoweringEmitter.cpp \
RegisterInfoEmitter.cpp \
- SetTheory.cpp \
SubtargetEmitter.cpp \
TableGen.cpp \
X86DisassemblerTables.cpp \
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 3d72741..1277086 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -1722,8 +1722,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
CvtOS << "void " << Target.getName() << ClassName << "::\n"
<< "convertToMCInst(unsigned Kind, MCInst &Inst, "
<< "unsigned Opcode,\n"
- << " const SmallVectorImpl<MCParsedAsmOperand*"
- << "> &Operands) {\n"
+ << " const OperandVector"
+ << " &Operands) {\n"
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
<< " const uint8_t *Converter = ConversionTable[Kind];\n"
<< " Inst.setOpcode(Opcode);\n"
@@ -1732,7 +1732,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n"
<< " case CVT_Reg:\n"
<< " static_cast<" << TargetOperandClass
- << "*>(Operands[*(p + 1)])->addRegOperands(Inst, 1);\n"
+ << "&>(*Operands[*(p + 1)]).addRegOperands(Inst, 1);\n"
<< " break;\n"
<< " case CVT_Tied:\n"
<< " Inst.addOperand(Inst.getOperand(*(p + 1)));\n"
@@ -1744,7 +1744,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
OpOS << "void " << Target.getName() << ClassName << "::\n"
<< "convertToMapAndConstraints(unsigned Kind,\n";
OpOS.indent(27);
- OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {\n"
+ OpOS << "const OperandVector &Operands) {\n"
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
<< " unsigned NumMCOperands = 0;\n"
<< " const uint8_t *Converter = ConversionTable[Kind];\n"
@@ -1849,9 +1849,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// converter driver.
CvtOS << " case " << Name << ":\n"
<< " static_cast<" << TargetOperandClass
- << "*>(Operands[*(p + 1)])->"
- << Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands
- << ");\n"
+ << "&>(*Operands[*(p + 1)])." << Op.Class->RenderMethod
+ << "(Inst, " << OpInfo.MINumOperands << ");\n"
<< " break;\n";
// Add a handler for the operand number lookup.
@@ -2036,10 +2035,10 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target,
/// emitValidateOperandClass - Emit the function to validate an operand class.
static void emitValidateOperandClass(AsmMatcherInfo &Info,
raw_ostream &OS) {
- OS << "static unsigned validateOperandClass(MCParsedAsmOperand *GOp, "
+ OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
<< "MatchClassKind Kind) {\n";
- OS << " " << Info.Target.getName() << "Operand &Operand = *("
- << Info.Target.getName() << "Operand*)GOp;\n";
+ OS << " " << Info.Target.getName() << "Operand &Operand = ("
+ << Info.Target.getName() << "Operand&)GOp;\n";
// The InvalidMatchClass is not to match any operand.
OS << " if (Kind == InvalidMatchClass)\n";
@@ -2561,7 +2560,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
// the found operand class.
OS << Target.getName() << ClassName << "::OperandMatchResultTy "
<< Target.getName() << ClassName << "::\n"
- << "tryCustomParseOperand(SmallVectorImpl<MCParsedAsmOperand*>"
+ << "tryCustomParseOperand(OperandVector"
<< " &Operands,\n unsigned MCK) {\n\n"
<< " switch(MCK) {\n";
@@ -2585,7 +2584,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
// a better error handling.
OS << Target.getName() << ClassName << "::OperandMatchResultTy "
<< Target.getName() << ClassName << "::\n"
- << "MatchOperandParserImpl(SmallVectorImpl<MCParsedAsmOperand*>"
+ << "MatchOperandParserImpl(OperandVector"
<< " &Operands,\n StringRef Mnemonic) {\n";
// Emit code to get the available features.
@@ -2695,14 +2694,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
<< "unsigned Opcode,\n"
- << " const SmallVectorImpl<MCParsedAsmOperand*> "
+ << " const OperandVector "
<< "&Operands);\n";
OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
- OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands) override;\n";
+ OS << " const OperandVector &Operands) override;\n";
OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n";
OS << " unsigned MatchInstructionImpl(\n";
OS.indent(27);
- OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
+ OS << "const OperandVector &Operands,\n"
<< " MCInst &Inst,\n"
<< " unsigned &ErrorInfo,"
<< " bool matchingInlineAsm,\n"
@@ -2715,11 +2714,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " MatchOperand_ParseFail // operand matched but had errors\n";
OS << " };\n";
OS << " OperandMatchResultTy MatchOperandParserImpl(\n";
- OS << " SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
+ OS << " OperandVector &Operands,\n";
OS << " StringRef Mnemonic);\n";
OS << " OperandMatchResultTy tryCustomParseOperand(\n";
- OS << " SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
+ OS << " OperandVector &Operands,\n";
OS << " unsigned MCK);\n\n";
}
@@ -2909,9 +2908,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << "}\n\n";
// Finally, build the match function.
- OS << "unsigned "
- << Target.getName() << ClassName << "::\n"
- << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
+ OS << "unsigned " << Target.getName() << ClassName << "::\n"
+ << "MatchInstructionImpl(const OperandVector"
<< " &Operands,\n";
OS << " MCInst &Inst,\n"
<< "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
@@ -2928,7 +2926,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // Get the instruction mnemonic, which is the first token.\n";
OS << " StringRef Mnemonic = ((" << Target.getName()
- << "Operand*)Operands[0])->getToken();\n\n";
+ << "Operand&)*Operands[0]).getToken();\n\n";
if (HasMnemonicAliases) {
OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
@@ -2980,7 +2978,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " if (!OperandsValid) ErrorInfo = i + 1;\n";
OS << " break;\n";
OS << " }\n";
- OS << " unsigned Diag = validateOperandClass(Operands[i+1],\n";
+ OS << " unsigned Diag = validateOperandClass(*Operands[i+1],\n";
OS.indent(43);
OS << "(MatchClassKind)it->Classes[i]);\n";
OS << " if (Diag == Match_Success)\n";
@@ -2988,7 +2986,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // If the generic handler indicates an invalid operand\n";
OS << " // failure, check for a special case.\n";
OS << " if (Diag == Match_InvalidOperand) {\n";
- OS << " Diag = validateTargetOperandClass(Operands[i+1],\n";
+ OS << " Diag = validateTargetOperandClass(*Operands[i+1],\n";
OS.indent(43);
OS << "(MatchClassKind)it->Classes[i]);\n";
OS << " if (Diag == Match_Success)\n";
@@ -3055,7 +3053,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
if (HasDeprecation) {
OS << " std::string Info;\n";
OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n";
- OS << " SMLoc Loc = ((" << Target.getName() << "Operand*)Operands[0])->getStartLoc();\n";
+ OS << " SMLoc Loc = ((" << Target.getName()
+ << "Operand&)*Operands[0]).getStartLoc();\n";
OS << " Parser.Warning(Loc, Info, None);\n";
OS << " }\n";
}
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 2741d8f..c7fe9df 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -806,6 +806,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
// before it can be matched to the mnemonic.
std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap;
+ // A list of MCOperandPredicates for all operands in use, and the reverse map
+ std::vector<const Record*> MCOpPredicates;
+ DenseMap<const Record*, unsigned> MCOpPredicateMap;
+
for (auto &Aliases : AliasMap) {
for (auto &Alias : Aliases.second) {
const CodeGenInstAlias *CGA = Alias.first;
@@ -832,6 +836,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
unsigned MIOpNum = 0;
for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
+ std::string Op = "MI->getOperand(" + llvm::utostr(MIOpNum) + ")";
+
const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];
switch (RO.Kind) {
@@ -858,9 +864,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (Rec->isSubClassOf("RegisterOperand"))
Rec = Rec->getValueAsDef("RegClass");
if (Rec->isSubClassOf("RegisterClass")) {
- Cond = std::string("MI->getOperand(") + llvm::utostr(MIOpNum) +
- ").isReg()";
- IAP->addCond(Cond);
+ IAP->addCond(Op + ".isReg()");
if (!IAP->isOpMapped(ROName)) {
IAP->addOperand(ROName, MIOpNum, PrintMethodIdx);
@@ -869,26 +873,34 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
R = R->getValueAsDef("RegClass");
Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" +
R->getName() + "RegClassID)"
- ".contains(MI->getOperand(" +
- llvm::utostr(MIOpNum) + ").getReg())";
- IAP->addCond(Cond);
+ ".contains(" + Op + ".getReg())";
} else {
- Cond = std::string("MI->getOperand(") +
- llvm::utostr(MIOpNum) + ").getReg() == MI->getOperand(" +
+ Cond = Op + ".getReg() == MI->getOperand(" +
llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()";
- IAP->addCond(Cond);
}
} else {
// Assume all printable operands are desired for now. This can be
// overridden in the InstAlias instantiation if necessary.
IAP->addOperand(ROName, MIOpNum, PrintMethodIdx);
- }
+ // There might be an additional predicate on the MCOperand
+ unsigned Entry = MCOpPredicateMap[Rec];
+ if (!Entry) {
+ if (!Rec->isValueUnset("MCOperandPredicate")) {
+ MCOpPredicates.push_back(Rec);
+ Entry = MCOpPredicates.size();
+ MCOpPredicateMap[Rec] = Entry;
+ } else
+ break; // No conditions on this operand at all
+ }
+ Cond = Target.getName() + ClassName + "ValidateMCOperand(" +
+ Op + ", " + llvm::utostr(Entry) + ")";
+ }
+ // for all subcases of ResultOperand::K_Record:
+ IAP->addCond(Cond);
break;
}
case CodeGenInstAlias::ResultOperand::K_Imm: {
- std::string Op = "MI->getOperand(" + llvm::utostr(MIOpNum) + ")";
-
// Just because the alias has an immediate result, doesn't mean the
// MCInst will. An MCExpr could be present, for example.
IAP->addCond(Op + ".isImm()");
@@ -906,8 +918,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
break;
}
- Cond = std::string("MI->getOperand(") +
- llvm::utostr(MIOpNum) + ").getReg() == " + Target.getName() +
+ Cond = Op + ".getReg() == " + Target.getName() +
"::" + CGA->ResultOperands[i].getRegister()->getName();
IAP->addCond(Cond);
break;
@@ -980,6 +991,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
return;
}
+ if (MCOpPredicates.size())
+ O << "static bool " << Target.getName() << ClassName
+ << "ValidateMCOperand(\n"
+ << " const MCOperand &MCOp, unsigned PredicateIndex);\n";
+
O << HeaderO.str();
O.indent(2) << "const char *AsmString;\n";
O.indent(2) << "switch (MI->getOpcode()) {\n";
@@ -1041,6 +1057,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
}
O << "}\n\n";
+ if (MCOpPredicates.size()) {
+ O << "static bool " << Target.getName() << ClassName
+ << "ValidateMCOperand(\n"
+ << " const MCOperand &MCOp, unsigned PredicateIndex) {\n"
+ << " switch (PredicateIndex) {\n"
+ << " default:\n"
+ << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
+ << " break;\n";
+
+ for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
+ Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate");
+ if (StringInit *SI = dyn_cast<StringInit>(MCOpPred)) {
+ O << " case " << i + 1 << ": {\n"
+ << SI->getValue() << "\n"
+ << " }\n";
+ } else
+ llvm_unreachable("Unexpected MCOperandPredicate field!");
+ }
+ O << " }\n"
+ << "}\n\n";
+ }
+
O << "#endif // PRINT_ALIAS_INSTR\n";
}
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index f277608..feaa7c7 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -26,7 +26,6 @@ add_tablegen(llvm-tblgen LLVM
OptParserEmitter.cpp
PseudoLoweringEmitter.cpp
RegisterInfoEmitter.cpp
- SetTheory.cpp
SubtargetEmitter.cpp
TableGen.cpp
X86DisassemblerTables.cpp
diff --git a/utils/TableGen/CTagsEmitter.cpp b/utils/TableGen/CTagsEmitter.cpp
index 7108679..5d6d6da 100644
--- a/utils/TableGen/CTagsEmitter.cpp
+++ b/utils/TableGen/CTagsEmitter.cpp
@@ -37,8 +37,8 @@ public:
: Id(&Name), Loc(Location) {}
int operator<(const Tag &B) const { return *Id < *B.Id; }
void emit(raw_ostream &OS) const {
- int BufferID = SrcMgr.FindBufferContainingLoc(Loc);
- MemoryBuffer *CurMB = SrcMgr.getBufferInfo(BufferID).Buffer;
+ const MemoryBuffer *CurMB =
+ SrcMgr.getMemoryBuffer(SrcMgr.FindBufferContainingLoc(Loc));
const char *BufferName = CurMB->getBufferIdentifier();
std::pair<unsigned, unsigned> LineAndColumn = SrcMgr.getLineAndColumn(Loc);
OS << *Id << "\t" << BufferName << "\t" << LineAndColumn.first << "\n";
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 00bc9a5..2602bbc 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2119,9 +2119,11 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) {
// If we have input named node types, propagate their types to the named
// values here.
if (InNamedTypes) {
- // FIXME: Should be error?
- assert(InNamedTypes->count(I->getKey()) &&
- "Named node in output pattern but not input pattern?");
+ if (!InNamedTypes->count(I->getKey())) {
+ error("Node '" + std::string(I->getKey()) +
+ "' in output pattern but not input pattern");
+ return true;
+ }
const SmallVectorImpl<TreePatternNode*> &InNodes =
InNamedTypes->find(I->getKey())->second;
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index 06daa97..a9ece01 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -28,6 +28,7 @@ namespace llvm {
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
std::string EnumName; // The name of the enum "bswap_i32"
std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
+ std::string MSBuiltinName; // Name of the corresponding MS builtin, or "".
std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics.
/// IntrinsicSignature - This structure holds the return values and
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 30732c8..278315b 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -15,7 +15,6 @@
#ifndef CODEGEN_REGISTERS_H
#define CODEGEN_REGISTERS_H
-#include "SetTheory.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
@@ -23,6 +22,7 @@
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/SetTheory.h"
#include <cstdlib>
#include <map>
#include <set>
diff --git a/utils/TableGen/CodeGenSchedule.h b/utils/TableGen/CodeGenSchedule.h
index 65ac602..3fef8ad 100644
--- a/utils/TableGen/CodeGenSchedule.h
+++ b/utils/TableGen/CodeGenSchedule.h
@@ -15,11 +15,11 @@
#ifndef CODEGEN_SCHEDULE_H
#define CODEGEN_SCHEDULE_H
-#include "SetTheory.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/SetTheory.h"
namespace llvm {
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index de00dc6..d1b5711 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -459,6 +459,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
+ if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field.
+ MSBuiltinName = R->getValueAsString("MSBuiltinName");
TargetPrefix = R->getValueAsString("TargetPrefix");
Name = R->getValueAsString("LLVMName");
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index 1927ad9..430ef32 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -54,6 +54,8 @@ public:
raw_ostream &OS);
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS);
+ void EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
+ raw_ostream &OS);
void EmitSuffix(raw_ostream &OS);
};
} // End anonymous namespace
@@ -96,6 +98,9 @@ void IntrinsicEmitter::run(raw_ostream &OS) {
// Emit code to translate GCC builtins into LLVM intrinsics.
EmitIntrinsicToGCCBuiltinMap(Ints, OS);
+ // Emit code to translate MS builtins into LLVM intrinsics.
+ EmitIntrinsicToMSBuiltinMap(Ints, OS);
+
EmitSuffix(OS);
}
@@ -380,7 +385,7 @@ static void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
case 3: TypeSig.push_back(IIT_STRUCT3); break;
case 4: TypeSig.push_back(IIT_STRUCT4); break;
case 5: TypeSig.push_back(IIT_STRUCT5); break;
- default: assert(0 && "Unhandled case in struct");
+ default: llvm_unreachable("Unhandled case in struct");
}
for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
@@ -790,6 +795,55 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
OS << "#endif\n\n";
}
+void IntrinsicEmitter::
+EmitIntrinsicToMSBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
+ raw_ostream &OS) {
+ std::map<std::string, std::map<std::string, std::string>> TargetBuiltins;
+
+ for (const auto &Intrinsic : Ints) {
+ if (Intrinsic.MSBuiltinName.empty())
+ continue;
+
+ auto &Builtins = TargetBuiltins[Intrinsic.TargetPrefix];
+ if (!Builtins.insert(std::make_pair(Intrinsic.MSBuiltinName,
+ Intrinsic.EnumName)).second)
+ PrintFatalError("Intrinsic '" + Intrinsic.TheDef->getName() + "': "
+ "duplicate MS builtin name!");
+ }
+
+ OS << "// Get the LLVM intrinsic that corresponds to a MS builtin.\n"
+ "// This is used by the C front-end. The MS builtin name is passed\n"
+ "// in as a BuiltinName, and a target prefix (e.g. 'arm') is passed\n"
+ "// in as a TargetPrefix. The result is assigned to 'IntrinsicID'.\n"
+ "#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN\n";
+
+ OS << (TargetOnly ? "static " + TargetPrefix : "") << "Intrinsic::ID "
+ << (TargetOnly ? "" : "Intrinsic::")
+ << "getIntrinsicForMSBuiltin(const char *TP, const char *BN) {\n";
+ OS << " StringRef BuiltinName(BN);\n"
+ " StringRef TargetPrefix(TP);\n"
+ "\n";
+
+ for (const auto &Builtins : TargetBuiltins) {
+ OS << " ";
+ if (Builtins.first.empty())
+ OS << "/* Target Independent Builtins */ ";
+ else
+ OS << "if (TargetPrefix == \"" << Builtins.first << "\") ";
+ OS << "{\n";
+ EmitTargetBuiltins(Builtins.second, TargetPrefix, OS);
+ OS << "}";
+ }
+
+ OS << " return ";
+ if (!TargetPrefix.empty())
+ OS << "(" << TargetPrefix << "Intrinsic::ID)";
+ OS << "Intrinsic::not_intrinsic;\n";
+ OS << "}\n";
+
+ OS << "#endif\n\n";
+}
+
void llvm::EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly) {
IntrinsicEmitter(RK, TargetOnly).run(OS);
}
diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp
deleted file mode 100644
index 5ead7ed..0000000
--- a/utils/TableGen/SetTheory.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-//===- SetTheory.cpp - Generate ordered sets from DAG expressions ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the SetTheory class that computes ordered sets of
-// Records from DAG expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SetTheory.h"
-#include "llvm/Support/Format.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
-
-using namespace llvm;
-
-// Define the standard operators.
-namespace {
-
-typedef SetTheory::RecSet RecSet;
-typedef SetTheory::RecVec RecVec;
-
-// (add a, b, ...) Evaluate and union all arguments.
-struct AddOp : public SetTheory::Operator {
- void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) override {
- ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
- }
-};
-
-// (sub Add, Sub, ...) Set difference.
-struct SubOp : public SetTheory::Operator {
- void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) override {
- if (Expr->arg_size() < 2)
- PrintFatalError(Loc, "Set difference needs at least two arguments: " +
- Expr->getAsString());
- RecSet Add, Sub;
- ST.evaluate(*Expr->arg_begin(), Add, Loc);
- ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Sub, Loc);
- for (RecSet::iterator I = Add.begin(), E = Add.end(); I != E; ++I)
- if (!Sub.count(*I))
- Elts.insert(*I);
- }
-};
-
-// (and S1, S2) Set intersection.
-struct AndOp : public SetTheory::Operator {
- void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) override {
- if (Expr->arg_size() != 2)
- PrintFatalError(Loc, "Set intersection requires two arguments: " +
- Expr->getAsString());
- RecSet S1, S2;
- ST.evaluate(Expr->arg_begin()[0], S1, Loc);
- ST.evaluate(Expr->arg_begin()[1], S2, Loc);
- for (RecSet::iterator I = S1.begin(), E = S1.end(); I != E; ++I)
- if (S2.count(*I))
- Elts.insert(*I);
- }
-};
-
-// SetIntBinOp - Abstract base class for (Op S, N) operators.
-struct SetIntBinOp : public SetTheory::Operator {
- virtual void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) = 0;
-
- void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) override {
- if (Expr->arg_size() != 2)
- PrintFatalError(Loc, "Operator requires (Op Set, Int) arguments: " +
- Expr->getAsString());
- RecSet Set;
- ST.evaluate(Expr->arg_begin()[0], Set, Loc);
- IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]);
- if (!II)
- PrintFatalError(Loc, "Second argument must be an integer: " +
- Expr->getAsString());
- apply2(ST, Expr, Set, II->getValue(), Elts, Loc);
- }
-};
-
-// (shl S, N) Shift left, remove the first N elements.
-struct ShlOp : public SetIntBinOp {
- void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) override {
- if (N < 0)
- PrintFatalError(Loc, "Positive shift required: " +
- Expr->getAsString());
- if (unsigned(N) < Set.size())
- Elts.insert(Set.begin() + N, Set.end());
- }
-};
-
-// (trunc S, N) Truncate after the first N elements.
-struct TruncOp : public SetIntBinOp {
- void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) override {
- if (N < 0)
- PrintFatalError(Loc, "Positive length required: " +
- Expr->getAsString());
- if (unsigned(N) > Set.size())
- N = Set.size();
- Elts.insert(Set.begin(), Set.begin() + N);
- }
-};
-
-// Left/right rotation.
-struct RotOp : public SetIntBinOp {
- const bool Reverse;
-
- RotOp(bool Rev) : Reverse(Rev) {}
-
- void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) override {
- if (Reverse)
- N = -N;
- // N > 0 -> rotate left, N < 0 -> rotate right.
- if (Set.empty())
- return;
- if (N < 0)
- N = Set.size() - (-N % Set.size());
- else
- N %= Set.size();
- Elts.insert(Set.begin() + N, Set.end());
- Elts.insert(Set.begin(), Set.begin() + N);
- }
-};
-
-// (decimate S, N) Pick every N'th element of S.
-struct DecimateOp : public SetIntBinOp {
- void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) override {
- if (N <= 0)
- PrintFatalError(Loc, "Positive stride required: " +
- Expr->getAsString());
- for (unsigned I = 0; I < Set.size(); I += N)
- Elts.insert(Set[I]);
- }
-};
-
-// (interleave S1, S2, ...) Interleave elements of the arguments.
-struct InterleaveOp : public SetTheory::Operator {
- void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) override {
- // Evaluate the arguments individually.
- SmallVector<RecSet, 4> Args(Expr->getNumArgs());
- unsigned MaxSize = 0;
- for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) {
- ST.evaluate(Expr->getArg(i), Args[i], Loc);
- MaxSize = std::max(MaxSize, unsigned(Args[i].size()));
- }
- // Interleave arguments into Elts.
- for (unsigned n = 0; n != MaxSize; ++n)
- for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i)
- if (n < Args[i].size())
- Elts.insert(Args[i][n]);
- }
-};
-
-// (sequence "Format", From, To) Generate a sequence of records by name.
-struct SequenceOp : public SetTheory::Operator {
- void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) override {
- int Step = 1;
- if (Expr->arg_size() > 4)
- PrintFatalError(Loc, "Bad args to (sequence \"Format\", From, To): " +
- Expr->getAsString());
- else if (Expr->arg_size() == 4) {
- if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[3])) {
- Step = II->getValue();
- } else
- PrintFatalError(Loc, "Stride must be an integer: " +
- Expr->getAsString());
- }
-
- std::string Format;
- if (StringInit *SI = dyn_cast<StringInit>(Expr->arg_begin()[0]))
- Format = SI->getValue();
- else
- PrintFatalError(Loc, "Format must be a string: " + Expr->getAsString());
-
- int64_t From, To;
- if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]))
- From = II->getValue();
- else
- PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString());
- if (From < 0 || From >= (1 << 30))
- PrintFatalError(Loc, "From out of range");
-
- if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[2]))
- To = II->getValue();
- else
- PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString());
- if (To < 0 || To >= (1 << 30))
- PrintFatalError(Loc, "To out of range");
-
- RecordKeeper &Records =
- cast<DefInit>(Expr->getOperator())->getDef()->getRecords();
-
- Step *= From <= To ? 1 : -1;
- while (true) {
- if (Step > 0 && From > To)
- break;
- else if (Step < 0 && From < To)
- break;
- std::string Name;
- raw_string_ostream OS(Name);
- OS << format(Format.c_str(), unsigned(From));
- Record *Rec = Records.getDef(OS.str());
- if (!Rec)
- PrintFatalError(Loc, "No def named '" + Name + "': " +
- Expr->getAsString());
- // Try to reevaluate Rec in case it is a set.
- if (const RecVec *Result = ST.expand(Rec))
- Elts.insert(Result->begin(), Result->end());
- else
- Elts.insert(Rec);
-
- From += Step;
- }
- }
-};
-
-// Expand a Def into a set by evaluating one of its fields.
-struct FieldExpander : public SetTheory::Expander {
- StringRef FieldName;
-
- FieldExpander(StringRef fn) : FieldName(fn) {}
-
- void expand(SetTheory &ST, Record *Def, RecSet &Elts) override {
- ST.evaluate(Def->getValueInit(FieldName), Elts, Def->getLoc());
- }
-};
-} // end anonymous namespace
-
-// Pin the vtables to this file.
-void SetTheory::Operator::anchor() {}
-void SetTheory::Expander::anchor() {}
-
-
-SetTheory::SetTheory() {
- addOperator("add", new AddOp);
- addOperator("sub", new SubOp);
- addOperator("and", new AndOp);
- addOperator("shl", new ShlOp);
- addOperator("trunc", new TruncOp);
- addOperator("rotl", new RotOp(false));
- addOperator("rotr", new RotOp(true));
- addOperator("decimate", new DecimateOp);
- addOperator("interleave", new InterleaveOp);
- addOperator("sequence", new SequenceOp);
-}
-
-void SetTheory::addOperator(StringRef Name, Operator *Op) {
- Operators[Name] = Op;
-}
-
-void SetTheory::addExpander(StringRef ClassName, Expander *E) {
- Expanders[ClassName] = E;
-}
-
-void SetTheory::addFieldExpander(StringRef ClassName, StringRef FieldName) {
- addExpander(ClassName, new FieldExpander(FieldName));
-}
-
-void SetTheory::evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc) {
- // A def in a list can be a just an element, or it may expand.
- if (DefInit *Def = dyn_cast<DefInit>(Expr)) {
- if (const RecVec *Result = expand(Def->getDef()))
- return Elts.insert(Result->begin(), Result->end());
- Elts.insert(Def->getDef());
- return;
- }
-
- // Lists simply expand.
- if (ListInit *LI = dyn_cast<ListInit>(Expr))
- return evaluate(LI->begin(), LI->end(), Elts, Loc);
-
- // Anything else must be a DAG.
- DagInit *DagExpr = dyn_cast<DagInit>(Expr);
- if (!DagExpr)
- PrintFatalError(Loc, "Invalid set element: " + Expr->getAsString());
- DefInit *OpInit = dyn_cast<DefInit>(DagExpr->getOperator());
- if (!OpInit)
- PrintFatalError(Loc, "Bad set expression: " + Expr->getAsString());
- Operator *Op = Operators.lookup(OpInit->getDef()->getName());
- if (!Op)
- PrintFatalError(Loc, "Unknown set operator: " + Expr->getAsString());
- Op->apply(*this, DagExpr, Elts, Loc);
-}
-
-const RecVec *SetTheory::expand(Record *Set) {
- // Check existing entries for Set and return early.
- ExpandMap::iterator I = Expansions.find(Set);
- if (I != Expansions.end())
- return &I->second;
-
- // This is the first time we see Set. Find a suitable expander.
- const std::vector<Record*> &SC = Set->getSuperClasses();
- for (unsigned i = 0, e = SC.size(); i != e; ++i) {
- // Skip unnamed superclasses.
- if (!dyn_cast<StringInit>(SC[i]->getNameInit()))
- continue;
- if (Expander *Exp = Expanders.lookup(SC[i]->getName())) {
- // This breaks recursive definitions.
- RecVec &EltVec = Expansions[Set];
- RecSet Elts;
- Exp->expand(*this, Set, Elts);
- EltVec.assign(Elts.begin(), Elts.end());
- return &EltVec;
- }
- }
-
- // Set is not expandable.
- return nullptr;
-}
-
diff --git a/utils/TableGen/SetTheory.h b/utils/TableGen/SetTheory.h
deleted file mode 100644
index 5baed79..0000000
--- a/utils/TableGen/SetTheory.h
+++ /dev/null
@@ -1,142 +0,0 @@
-//===- SetTheory.h - Generate ordered sets from DAG expressions -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the SetTheory class that computes ordered sets of
-// Records from DAG expressions. Operators for standard set operations are
-// predefined, and it is possible to add special purpose set operators as well.
-//
-// The user may define named sets as Records of predefined classes. Set
-// expanders can be added to a SetTheory instance to teach it how to find the
-// elements of such a named set.
-//
-// These are the predefined operators. The argument lists can be individual
-// elements (defs), other sets (defs of expandable classes), lists, or DAG
-// expressions that are evaluated recursively.
-//
-// - (add S1, S2 ...) Union sets. This is also how sets are created from element
-// lists.
-//
-// - (sub S1, S2, ...) Set difference. Every element in S1 except for the
-// elements in S2, ...
-//
-// - (and S1, S2) Set intersection. Every element in S1 that is also in S2.
-//
-// - (shl S, N) Shift left. Remove the first N elements from S.
-//
-// - (trunc S, N) Truncate. The first N elements of S.
-//
-// - (rotl S, N) Rotate left. Same as (add (shl S, N), (trunc S, N)).
-//
-// - (rotr S, N) Rotate right.
-//
-// - (decimate S, N) Decimate S by picking every N'th element, starting with
-// the first one. For instance, (decimate S, 2) returns the even elements of
-// S.
-//
-// - (sequence "Format", From, To) Generate a sequence of defs with printf.
-// For instance, (sequence "R%u", 0, 3) -> [ R0, R1, R2, R3 ]
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SETTHEORY_H
-#define SETTHEORY_H
-
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/SourceMgr.h"
-#include <map>
-#include <vector>
-
-namespace llvm {
-
-class DagInit;
-class Init;
-class Record;
-class RecordKeeper;
-
-class SetTheory {
-public:
- typedef std::vector<Record*> RecVec;
- typedef SmallSetVector<Record*, 16> RecSet;
-
- /// Operator - A callback representing a DAG operator.
- class Operator {
- virtual void anchor();
- public:
- virtual ~Operator() {}
-
- /// apply - Apply this operator to Expr's arguments and insert the result
- /// in Elts.
- virtual void apply(SetTheory&, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) =0;
- };
-
- /// Expander - A callback function that can transform a Record representing a
- /// set into a fully expanded list of elements. Expanders provide a way for
- /// users to define named sets that can be used in DAG expressions.
- class Expander {
- virtual void anchor();
- public:
- virtual ~Expander() {}
-
- virtual void expand(SetTheory&, Record*, RecSet &Elts) =0;
- };
-
-private:
- // Map set defs to their fully expanded contents. This serves as a memoization
- // cache and it makes it possible to return const references on queries.
- typedef std::map<Record*, RecVec> ExpandMap;
- ExpandMap Expansions;
-
- // Known DAG operators by name.
- StringMap<Operator*> Operators;
-
- // Typed expanders by class name.
- StringMap<Expander*> Expanders;
-
-public:
- /// Create a SetTheory instance with only the standard operators.
- SetTheory();
-
- /// addExpander - Add an expander for Records with the named super class.
- void addExpander(StringRef ClassName, Expander*);
-
- /// addFieldExpander - Add an expander for ClassName that simply evaluates
- /// FieldName in the Record to get the set elements. That is all that is
- /// needed for a class like:
- ///
- /// class Set<dag d> {
- /// dag Elts = d;
- /// }
- ///
- void addFieldExpander(StringRef ClassName, StringRef FieldName);
-
- /// addOperator - Add a DAG operator.
- void addOperator(StringRef Name, Operator*);
-
- /// evaluate - Evaluate Expr and append the resulting set to Elts.
- void evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc);
-
- /// evaluate - Evaluate a sequence of Inits and append to Elts.
- template<typename Iter>
- void evaluate(Iter begin, Iter end, RecSet &Elts, ArrayRef<SMLoc> Loc) {
- while (begin != end)
- evaluate(*begin++, Elts, Loc);
- }
-
- /// expand - Expand a record into a set of elements if possible. Return a
- /// pointer to the expanded elements, or NULL if Set cannot be expanded
- /// further.
- const RecVec *expand(Record *Set);
-};
-
-} // end namespace llvm
-
-#endif
-
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 00c3a6f..bbd61f5 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -12,13 +12,13 @@
//===----------------------------------------------------------------------===//
#include "TableGenBackends.h" // Declares all backends.
-#include "SetTheory.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Main.h"
#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/SetTheory.h"
using namespace llvm;