summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/utils
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-02-27 01:32:10 +0000
committerdim <dim@FreeBSD.org>2011-02-27 01:32:10 +0000
commitb951d621be1d00a520871c689c1cd687b6aa3ae6 (patch)
tree5c342f2374324ffec4626f558d9aa49f323f90b4 /contrib/llvm/utils
parent4004d6a3076e94bd23e681411c43682267a202fe (diff)
parenta0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff)
downloadFreeBSD-src-b951d621be1d00a520871c689c1cd687b6aa3ae6.zip
FreeBSD-src-b951d621be1d00a520871c689c1cd687b6aa3ae6.tar.gz
Update llvm/clang to trunk r126547.
There are several bugfixes in this update, but the most important one is to ensure __start_ and __stop_ symbols for linker sets and kernel module metadata are always emitted in object files: http://llvm.org/bugs/show_bug.cgi?id=9292 Before this fix, if you compiled kernel modules with clang, they would not be properly processed by kldxref, and if they had any dependencies, the kernel would fail to load those. Another problem occurred when attempting to mount a tmpfs filesystem, which would result in 'operation not supported by device'.
Diffstat (limited to 'contrib/llvm/utils')
-rw-r--r--contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp249
-rw-r--r--contrib/llvm/utils/TableGen/AsmWriterEmitter.h1
-rw-r--r--contrib/llvm/utils/TableGen/ClangSACheckersEmitter.cpp1
-rw-r--r--contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp4
4 files changed, 254 insertions, 1 deletions
diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 448ebad..cd31e0c 100644
--- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -542,7 +542,255 @@ void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) {
<< "}\n\n#endif\n";
}
+void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
+ CodeGenTarget Target(Records);
+ Record *AsmWriter = Target.getAsmWriter();
+
+ O << "\n#ifdef PRINT_ALIAS_INSTR\n";
+ O << "#undef PRINT_ALIAS_INSTR\n\n";
+
+ // Enumerate the register classes.
+ const std::vector<CodeGenRegisterClass> &RegisterClasses =
+ Target.getRegisterClasses();
+
+ O << "namespace { // Register classes\n";
+ O << " enum RegClass {\n";
+
+ // Emit the register enum value for each RegisterClass.
+ for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) {
+ if (I != 0) O << ",\n";
+ O << " RC_" << RegisterClasses[I].TheDef->getName();
+ }
+
+ O << "\n };\n";
+ O << "} // end anonymous namespace\n\n";
+
+ // Emit a function that returns 'true' if a regsiter is part of a particular
+ // register class. I.e., RAX is part of GR64 on X86.
+ O << "static bool regIsInRegisterClass"
+ << "(unsigned RegClass, unsigned Reg) {\n";
+
+ // Emit the switch that checks if a register belongs to a particular register
+ // class.
+ O << " switch (RegClass) {\n";
+ O << " default: break;\n";
+
+ for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) {
+ const CodeGenRegisterClass &RC = RegisterClasses[I];
+
+ // Give the register class a legal C name if it's anonymous.
+ std::string Name = RC.TheDef->getName();
+ O << " case RC_" << Name << ":\n";
+
+ // Emit the register list now.
+ unsigned IE = RC.Elements.size();
+ if (IE == 1) {
+ O << " if (Reg == " << getQualifiedName(RC.Elements[0]) << ")\n";
+ O << " return true;\n";
+ } else {
+ O << " switch (Reg) {\n";
+ O << " default: break;\n";
+
+ for (unsigned II = 0; II != IE; ++II) {
+ Record *Reg = RC.Elements[II];
+ O << " case " << getQualifiedName(Reg) << ":\n";
+ }
+
+ O << " return true;\n";
+ O << " }\n";
+ }
+
+ O << " break;\n";
+ }
+
+ O << " }\n\n";
+ O << " return false;\n";
+ O << "}\n\n";
+
+ // Emit the method that prints the alias instruction.
+ std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+ bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter");
+ const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr";
+
+ O << "bool " << Target.getName() << ClassName
+ << "::printAliasInstr(const " << MachineInstrClassName
+ << " *MI, raw_ostream &OS) {\n";
+
+ std::vector<Record*> AllInstAliases =
+ Records.getAllDerivedDefinitions("InstAlias");
+
+ // Create a map from the qualified name to a list of potential matches.
+ std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap;
+ for (std::vector<Record*>::iterator
+ I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) {
+ CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target);
+ const Record *R = *I;
+ const DagInit *DI = R->getValueAsDag("ResultInst");
+ const DefInit *Op = dynamic_cast<const DefInit*>(DI->getOperator());
+ AliasMap[getQualifiedName(Op->getDef())].push_back(Alias);
+ }
+
+ if (AliasMap.empty() || !isMC) {
+ // FIXME: Support MachineInstr InstAliases?
+ O << " return true;\n";
+ O << "}\n\n";
+ O << "#endif // PRINT_ALIAS_INSTR\n";
+ return;
+ }
+
+ O << " StringRef AsmString;\n";
+ O << " std::map<StringRef, unsigned> OpMap;\n";
+ O << " switch (MI->getOpcode()) {\n";
+ O << " default: return true;\n";
+
+ for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator
+ I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) {
+ std::vector<CodeGenInstAlias*> &Aliases = I->second;
+
+ std::map<std::string, unsigned> CondCount;
+ std::map<std::string, std::string> BodyMap;
+
+ std::string AsmString = "";
+
+ for (std::vector<CodeGenInstAlias*>::iterator
+ II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) {
+ const CodeGenInstAlias *CGA = *II;
+ AsmString = CGA->AsmString;
+ unsigned Indent = 8;
+ unsigned LastOpNo = CGA->ResultInstOperandIndex.size();
+
+ std::string Cond;
+ raw_string_ostream CondO(Cond);
+
+ CondO << "if (MI->getNumOperands() == " << LastOpNo;
+
+ std::map<StringRef, unsigned> OpMap;
+ bool CantHandle = false;
+
+ for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
+ const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];
+
+ switch (RO.Kind) {
+ default: assert(0 && "unexpected InstAlias operand kind");
+ case CodeGenInstAlias::ResultOperand::K_Record: {
+ const Record *Rec = RO.getRecord();
+ StringRef ROName = RO.getName();
+
+ if (Rec->isSubClassOf("RegisterClass")) {
+ CondO << " &&\n";
+ CondO.indent(Indent) << "MI->getOperand(" << i << ").isReg() &&\n";
+ if (OpMap.find(ROName) == OpMap.end()) {
+ OpMap[ROName] = i;
+ CondO.indent(Indent)
+ << "regIsInRegisterClass(RC_"
+ << CGA->ResultOperands[i].getRecord()->getName()
+ << ", MI->getOperand(" << i << ").getReg())";
+ } else {
+ CondO.indent(Indent)
+ << "MI->getOperand(" << i
+ << ").getReg() == MI->getOperand("
+ << OpMap[ROName] << ").getReg()";
+ }
+ } else {
+ assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
+ // FIXME: We need to handle these situations.
+ CantHandle = true;
+ break;
+ }
+
+ break;
+ }
+ case CodeGenInstAlias::ResultOperand::K_Imm:
+ CondO << " &&\n";
+ CondO.indent(Indent) << "MI->getOperand(" << i << ").getImm() == ";
+ CondO << CGA->ResultOperands[i].getImm();
+ break;
+ case CodeGenInstAlias::ResultOperand::K_Reg:
+ CondO << " &&\n";
+ CondO.indent(Indent) << "MI->getOperand(" << i << ").getReg() == ";
+ CondO << Target.getName() << "::"
+ << CGA->ResultOperands[i].getRegister()->getName();
+ break;
+ }
+
+ if (CantHandle) break;
+ }
+
+ if (CantHandle) continue;
+
+ CondO << ")";
+
+ std::string Body;
+ raw_string_ostream BodyO(Body);
+
+ BodyO << " // " << CGA->Result->getAsString() << "\n";
+ BodyO << " AsmString = \"" << AsmString << "\";\n";
+
+ for (std::map<StringRef, unsigned>::iterator
+ III = OpMap.begin(), IIE = OpMap.end(); III != IIE; ++III)
+ BodyO << " OpMap[\"" << III->first << "\"] = "
+ << III->second << ";\n";
+
+ ++CondCount[CondO.str()];
+ BodyMap[CondO.str()] = BodyO.str();
+ }
+
+ std::string Code;
+ raw_string_ostream CodeO(Code);
+
+ bool EmitElse = false;
+ for (std::map<std::string, unsigned>::iterator
+ II = CondCount.begin(), IE = CondCount.end(); II != IE; ++II) {
+ if (II->second != 1) continue;
+ CodeO << " ";
+ if (EmitElse) CodeO << "} else ";
+ CodeO << II->first << " {\n";
+ CodeO << BodyMap[II->first];
+ EmitElse = true;
+ }
+
+ if (CodeO.str().empty()) continue;
+
+ O << " case " << I->first << ":\n";
+ O << CodeO.str();
+ O << " }\n";
+ O << " break;\n";
+ }
+
+ O << " }\n\n";
+
+ // Code that prints the alias, replacing the operands with the ones from the
+ // MCInst.
+ O << " if (AsmString.empty()) return true;\n";
+ O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n";
+ O << " OS << '\\t' << ASM.first;\n";
+
+ O << " if (!ASM.second.empty()) {\n";
+ O << " OS << '\\t';\n";
+ O << " for (StringRef::iterator\n";
+ O << " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n";
+ O << " if (*I == '$') {\n";
+ O << " StringRef::iterator Start = ++I;\n";
+ O << " while (I != E &&\n";
+ O << " ((*I >= 'a' && *I <= 'z') ||\n";
+ O << " (*I >= 'A' && *I <= 'Z') ||\n";
+ O << " (*I >= '0' && *I <= '9') ||\n";
+ O << " *I == '_'))\n";
+ O << " ++I;\n";
+ O << " StringRef Name(Start, I - Start);\n";
+ O << " printOperand(MI, OpMap[Name], OS);\n";
+ O << " } else {\n";
+ O << " OS << *I++;\n";
+ O << " }\n";
+ O << " }\n";
+ O << " }\n\n";
+
+ O << " return false;\n";
+ O << "}\n\n";
+
+ O << "#endif // PRINT_ALIAS_INSTR\n";
+}
void AsmWriterEmitter::run(raw_ostream &O) {
EmitSourceFileHeader("Assembly Writer Source Fragment", O);
@@ -550,5 +798,6 @@ void AsmWriterEmitter::run(raw_ostream &O) {
EmitPrintInstruction(O);
EmitGetRegisterName(O);
EmitGetInstructionName(O);
+ EmitPrintAliasInstruction(O);
}
diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.h b/contrib/llvm/utils/TableGen/AsmWriterEmitter.h
index 9f7d776..5e8d6f5 100644
--- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.h
+++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.h
@@ -38,6 +38,7 @@ private:
void EmitPrintInstruction(raw_ostream &o);
void EmitGetRegisterName(raw_ostream &o);
void EmitGetInstructionName(raw_ostream &o);
+ void EmitPrintAliasInstruction(raw_ostream &O);
AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
assert(ID < NumberedInstructions.size());
diff --git a/contrib/llvm/utils/TableGen/ClangSACheckersEmitter.cpp b/contrib/llvm/utils/TableGen/ClangSACheckersEmitter.cpp
index 3e49ab1..8865db3 100644
--- a/contrib/llvm/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -148,6 +148,7 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {
// Create a pseudo-group to hold this checker.
std::string fullName = getCheckerFullName(R);
GroupInfo &info = groupInfoByName[fullName];
+ info.Hidden = R->getValueAsBit("Hidden");
recordGroupMap[R] = &info;
info.Checkers.push_back(R);
} else {
diff --git a/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp b/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp
index ccd3efd..b0839c3 100644
--- a/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -34,7 +34,9 @@ using namespace llvm;
MAP(E8, 39) \
MAP(F0, 40) \
MAP(F8, 41) \
- MAP(F9, 42)
+ MAP(F9, 42) \
+ MAP(D0, 45) \
+ MAP(D1, 46)
// A clone of X86 since we can't depend on something that is generated.
namespace X86Local {
OpenPOWER on IntegriCloud