diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-26 20:32:52 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-26 20:32:52 +0000 |
commit | 08bbd35a80bf7765fe0d3043f9eb5a2f2786b649 (patch) | |
tree | 80108f0f128657f8623f8f66ad9735b4d88e7b47 /utils | |
parent | 7c7aba6e5fef47a01a136be655b0a92cfd7090f6 (diff) | |
download | src-test2-08bbd35a80bf7765fe0d3043f9eb5a2f2786b649.tar.gz src-test2-08bbd35a80bf7765fe0d3043f9eb5a2f2786b649.zip |
Notes
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 30 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 12 | ||||
-rw-r--r-- | utils/TableGen/DAGISelMatcherGen.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/GlobalISelEmitter.cpp | 120 | ||||
-rw-r--r-- | utils/TableGen/OptParserEmitter.cpp | 10 | ||||
-rwxr-xr-x | utils/opt-viewer/opt-stats.py | 6 | ||||
-rwxr-xr-x | utils/opt-viewer/opt-viewer.py | 4 | ||||
-rw-r--r-- | utils/opt-viewer/optrecord.py | 24 | ||||
-rwxr-xr-x | utils/release/test-release.sh | 8 |
9 files changed, 151 insertions, 69 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 7c41d9fad696..03914ef98952 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2762,8 +2762,8 @@ public: AnalyzeNode(Pat->getTree(0)); } - void Analyze(const PatternToMatch *Pat) { - AnalyzeNode(Pat->getSrcPattern()); + void Analyze(const PatternToMatch &Pat) { + AnalyzeNode(Pat.getSrcPattern()); } private: @@ -3220,7 +3220,7 @@ static void FindNames(const TreePatternNode *P, } void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, - const PatternToMatch &PTM) { + PatternToMatch &&PTM) { // Do some sanity checking on the pattern we're about to match. std::string Reason; if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) { @@ -3259,7 +3259,7 @@ void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, SrcNames[Entry.first].second == 1) Pattern->error("Pattern has dead named input: $" + Entry.first); - PatternsToMatch.push_back(PTM); + PatternsToMatch.push_back(std::move(PTM)); } @@ -3289,9 +3289,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() { // Second, look for single-instruction patterns defined outside the // instruction. - for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) { - const PatternToMatch &PTM = *I; - + for (const PatternToMatch &PTM : ptms()) { // We can only infer from single-instruction patterns, otherwise we won't // know which instruction should get the flags. SmallVector<Record*, 8> PatInstrs; @@ -3307,7 +3305,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() { continue; InstAnalyzer PatInfo(*this); - PatInfo.Analyze(&PTM); + PatInfo.Analyze(PTM); Errors += InferFromPattern(InstInfo, PatInfo, PTM.getSrcRecord()); } @@ -3367,7 +3365,7 @@ void CodeGenDAGPatterns::VerifyInstructionFlags() { // Analyze the source pattern. InstAnalyzer PatInfo(*this); - PatInfo.Analyze(&PTM); + PatInfo.Analyze(PTM); // Collect error messages. SmallVector<std::string, 4> Msgs; @@ -3553,14 +3551,12 @@ void CodeGenDAGPatterns::ParsePatterns() { TreePattern Temp(Result.getRecord(), DstPattern, false, *this); Temp.InferAllTypes(); - - AddPatternToMatch(Pattern, - PatternToMatch(CurPattern, - CurPattern->getValueAsListInit("Predicates"), - Pattern->getTree(0), - Temp.getOnlyTree(), InstImpResults, - CurPattern->getValueAsInt("AddedComplexity"), - CurPattern->getID())); + AddPatternToMatch( + Pattern, + PatternToMatch( + CurPattern, CurPattern->getValueAsListInit("Predicates"), + Pattern->getTree(0), Temp.getOnlyTree(), std::move(InstImpResults), + CurPattern->getValueAsInt("AddedComplexity"), CurPattern->getID())); } } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 5c56fb644e7f..8b3e19142370 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -684,12 +684,12 @@ public: /// processed to produce isel. class PatternToMatch { public: - PatternToMatch(Record *srcrecord, ListInit *preds, - TreePatternNode *src, TreePatternNode *dst, - const std::vector<Record*> &dstregs, + PatternToMatch(Record *srcrecord, ListInit *preds, TreePatternNode *src, + TreePatternNode *dst, std::vector<Record *> dstregs, int complexity, unsigned uid) - : SrcRecord(srcrecord), Predicates(preds), SrcPattern(src), DstPattern(dst), - Dstregs(dstregs), AddedComplexity(complexity), ID(uid) {} + : SrcRecord(srcrecord), Predicates(preds), SrcPattern(src), + DstPattern(dst), Dstregs(std::move(dstregs)), + AddedComplexity(complexity), ID(uid) {} Record *SrcRecord; // Originating Record for the pattern. ListInit *Predicates; // Top level predicate conditions to match. @@ -853,7 +853,7 @@ private: void GenerateVariants(); void VerifyInstructionFlags(); - void AddPatternToMatch(TreePattern *Pattern, const PatternToMatch &PTM); + void AddPatternToMatch(TreePattern *Pattern, PatternToMatch &&PTM); void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, std::map<std::string, TreePatternNode*> &InstInputs, diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index aafc1157893e..d239f96d2a60 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -848,8 +848,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other) HandledReg = II.ImplicitDefs[0]; - for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) { - Record *Reg = Pattern.getDstRegs()[i]; + for (Record *Reg : Pattern.getDstRegs()) { if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue; ResultVTs.push_back(getRegisterValueType(Reg, CGT)); } @@ -972,8 +971,7 @@ void MatcherGen::EmitResultCode() { HandledReg = II.ImplicitDefs[0]; } - for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) { - Record *Reg = Pattern.getDstRegs()[i]; + for (Record *Reg : Pattern.getDstRegs()) { if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue; ++NumSrcResults; } diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index 88ded1f25ffb..03d231a153dc 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -158,6 +158,16 @@ static Error isTrivialOperatorNode(const TreePatternNode *N) { return failedImport(Explanation); } +static Record *getInitValueAsRegClass(Init *V) { + if (DefInit *VDefInit = dyn_cast<DefInit>(V)) { + if (VDefInit->getDef()->isSubClassOf("RegisterOperand")) + return VDefInit->getDef()->getValueAsDef("RegClass"); + if (VDefInit->getDef()->isSubClassOf("RegisterClass")) + return VDefInit->getDef(); + } + return nullptr; +} + //===- Matchers -----------------------------------------------------------===// class OperandMatcher; @@ -973,6 +983,7 @@ public: /// into the desired instruction when this is possible. class BuildMIAction : public MatchAction { private: + std::string Name; const CodeGenInstruction *I; const InstructionMatcher &Matched; std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers; @@ -996,8 +1007,9 @@ private: } public: - BuildMIAction(const CodeGenInstruction *I, const InstructionMatcher &Matched) - : I(I), Matched(Matched) {} + BuildMIAction(const StringRef Name, const CodeGenInstruction *I, + const InstructionMatcher &Matched) + : Name(Name), I(I), Matched(Matched) {} template <class Kind, class... Args> Kind &addRenderer(Args&&... args) { @@ -1032,7 +1044,7 @@ public: } } - OS << " MachineInstr &NewI = " << RecycleVarName << ";\n"; + OS << " MachineInstr &" << Name << " = " << RecycleVarName << ";\n"; return; } @@ -1050,7 +1062,40 @@ public: OS << " for (const auto &MMO : FromMI->memoperands())\n"; OS << " MIB.addMemOperand(MMO);\n"; OS << " " << RecycleVarName << ".eraseFromParent();\n"; - OS << " MachineInstr &NewI = *MIB;\n"; + OS << " MachineInstr &" << Name << " = *MIB;\n"; + } +}; + +/// Generates code to constrain the operands of an output instruction to the +/// register classes specified by the definition of that instruction. +class ConstrainOperandsToDefinitionAction : public MatchAction { + std::string Name; + +public: + ConstrainOperandsToDefinitionAction(const StringRef Name) : Name(Name) {} + + void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule, + StringRef RecycleVarName) const override { + OS << " constrainSelectedInstRegOperands(" << Name << ", TII, TRI, RBI);\n"; + } +}; + +/// Generates code to constrain the specified operand of an output instruction +/// to the specified register class. +class ConstrainOperandToRegClassAction : public MatchAction { + std::string Name; + unsigned OpIdx; + const CodeGenRegisterClass &RC; + +public: + ConstrainOperandToRegClassAction(const StringRef Name, unsigned OpIdx, + const CodeGenRegisterClass &RC) + : Name(Name), OpIdx(OpIdx), RC(RC) {} + + void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule, + StringRef RecycleVarName) const override { + OS << " constrainOperandRegToRegClass(" << Name << ", " << OpIdx + << ", " << RC.getQualifiedName() << "RegClass, TII, TRI, RBI);\n"; } }; @@ -1205,7 +1250,6 @@ void RuleMatcher::emit(raw_ostream &OS, MA->emitCxxActionStmts(OS, *this, "I"); } - OS << " constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);\n"; OS << " return true;\n"; OS << " }\n"; OS << " return false;\n"; @@ -1439,15 +1483,10 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher, auto *ChildRec = ChildDefInit->getDef(); // Check for register classes. - if (ChildRec->isSubClassOf("RegisterClass")) { - OM.addPredicate<RegisterBankOperandMatcher>( - Target.getRegisterClass(ChildRec)); - return Error::success(); - } - - if (ChildRec->isSubClassOf("RegisterOperand")) { + if (ChildRec->isSubClassOf("RegisterClass") || + ChildRec->isSubClassOf("RegisterOperand")) { OM.addPredicate<RegisterBankOperandMatcher>( - Target.getRegisterClass(ChildRec->getValueAsDef("RegClass"))); + Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit))); return Error::success(); } @@ -1554,22 +1593,33 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( "Pattern operator isn't an instruction (it's a ValueType)"); return failedImport("Pattern operator isn't an instruction"); } - auto &DstI = Target.getInstruction(DstOp); + CodeGenInstruction *DstI = &Target.getInstruction(DstOp); + + unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs; + unsigned ExpectedDstINumUses = Dst->getNumChildren(); + + // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction + // attached. + if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") { + DstI = &Target.getInstruction(RK.getDef("COPY")); + DstINumUses--; // Ignore the class constraint. + ExpectedDstINumUses--; + } - auto &DstMIBuilder = M.addAction<BuildMIAction>(&DstI, InsnMatcher); + auto &DstMIBuilder = M.addAction<BuildMIAction>("NewI", DstI, InsnMatcher); // Render the explicit defs. - for (unsigned I = 0; I < DstI.Operands.NumDefs; ++I) { - const auto &DstIOperand = DstI.Operands[I]; + for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) { + const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I]; DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, DstIOperand.Name); } // Render the explicit uses. unsigned Child = 0; - unsigned DstINumUses = DstI.Operands.size() - DstI.Operands.NumDefs; unsigned NumDefaultOps = 0; for (unsigned I = 0; I != DstINumUses; ++I) { - const auto &DstIOperand = DstI.Operands[DstI.Operands.NumDefs + I]; + const CGIOperandList::OperandInfo &DstIOperand = + DstI->Operands[DstI->Operands.NumDefs + I]; // If the operand has default values, introduce them now. // FIXME: Until we have a decent test case that dictates we should do @@ -1590,10 +1640,10 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( ++Child; } - if (NumDefaultOps + Dst->getNumChildren() != DstINumUses) + if (NumDefaultOps + ExpectedDstINumUses != DstINumUses) return failedImport("Expected " + llvm::to_string(DstINumUses) + " used operands but found " + - llvm::to_string(Dst->getNumChildren()) + + llvm::to_string(ExpectedDstINumUses) + " explicit ones and " + llvm::to_string(NumDefaultOps) + " default ones"); @@ -1684,10 +1734,16 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { const auto &DstIOperand = DstI.Operands[OpIdx]; Record *DstIOpRec = DstIOperand.Rec; - if (DstIOpRec->isSubClassOf("RegisterOperand")) + if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") { + DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue()); + + if (DstIOpRec == nullptr) + return failedImport( + "COPY_TO_REGCLASS operand #1 isn't a register class"); + } else if (DstIOpRec->isSubClassOf("RegisterOperand")) DstIOpRec = DstIOpRec->getValueAsDef("RegClass"); - if (!DstIOpRec->isSubClassOf("RegisterClass")) - return failedImport("Dst MI def isn't a register class"); + else if (!DstIOpRec->isSubClassOf("RegisterClass")) + return failedImport("Dst MI def isn't a register class" + to_string(*Dst)); OperandMatcher &OM = InsnMatcher.getOperand(OpIdx); OM.setSymbolicName(DstIOperand.Name); @@ -1707,6 +1763,22 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs())) return std::move(Error); + // Constrain the registers to classes. This is normally derived from the + // emitted instruction but a few instructions require special handling. + if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") { + // COPY_TO_REGCLASS does not provide operand constraints itself but the + // result is constrained to the class given by the second child. + Record *DstIOpRec = + getInitValueAsRegClass(Dst->getChild(1)->getLeafValue()); + + if (DstIOpRec == nullptr) + return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class"); + + M.addAction<ConstrainOperandToRegClassAction>( + "NewI", 0, Target.getRegisterClass(DstIOpRec)); + } else + M.addAction<ConstrainOperandsToDefinitionAction>("NewI"); + // We're done with this pattern! It's eligible for GISel emission; return it. ++NumPatternImported; return std::move(M); diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp index 04e6537f3d15..e3777d036a23 100644 --- a/utils/TableGen/OptParserEmitter.cpp +++ b/utils/TableGen/OptParserEmitter.cpp @@ -196,6 +196,9 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { OS << ", nullptr"; // The option meta-variable name (unused). + OS << ", nullptr"; + + // The option Values (unused for groups). OS << ", nullptr)\n"; } OS << "\n"; @@ -285,6 +288,13 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { else OS << "nullptr"; + // The option Values. Used for shell autocompletion. + OS << ", "; + if (!isa<UnsetInit>(R.getValueInit("Values"))) + write_cstring(OS, R.getValueAsString("Values")); + else + OS << "nullptr"; + OS << ")\n"; } OS << "#endif // OPTION\n"; diff --git a/utils/opt-viewer/opt-stats.py b/utils/opt-viewer/opt-stats.py index 7ce935b492c5..79e5c03eca9f 100755 --- a/utils/opt-viewer/opt-stats.py +++ b/utils/opt-viewer/opt-stats.py @@ -24,10 +24,6 @@ if __name__ == '__main__': help='Max job count (defaults to %(default)s, the current CPU count)') args = parser.parse_args() - if len(args.yaml_files) == 0: - parser.print_help() - sys.exit(1) - if args.jobs == 1: pmap = map else: @@ -38,7 +34,7 @@ if __name__ == '__main__': bypass = defaultdict(int) byname = defaultdict(int) - for r in all_remarks.itervalues(): + for r in optrecord.itervalues(all_remarks): bypass[r.Pass] += 1 byname[r.Pass + "/" + r.Name] += 1 diff --git a/utils/opt-viewer/opt-viewer.py b/utils/opt-viewer/opt-viewer.py index 5e076d86dbe9..3f5503f26b1f 100755 --- a/utils/opt-viewer/opt-viewer.py +++ b/utils/opt-viewer/opt-viewer.py @@ -216,10 +216,6 @@ if __name__ == '__main__': help='set source directory') args = parser.parse_args() - if len(args.yaml_files) == 0: - parser.print_help() - sys.exit(1) - if args.jobs == 1: pmap = map else: diff --git a/utils/opt-viewer/optrecord.py b/utils/opt-viewer/optrecord.py index 2f930a48a056..6dc1a32e536a 100644 --- a/utils/opt-viewer/optrecord.py +++ b/utils/opt-viewer/optrecord.py @@ -24,14 +24,32 @@ p = subprocess.Popen(['c++filt', '-n'], stdin=subprocess.PIPE, stdout=subprocess p_lock = Lock() +try: + dict.iteritems +except AttributeError: + # Python 3 + def itervalues(d): + return iter(d.values()) + def iteritems(d): + return iter(d.items()) +else: + # Python 2 + def itervalues(d): + return d.itervalues() + def iteritems(d): + return d.iteritems() + + def demangle(name): with p_lock: p.stdin.write(name + '\n') return p.stdout.readline().rstrip() + def html_file_name(filename): return filename.replace('/', '_') + ".html" + def make_link(File, Line): return "\"{}#L{}\"".format(html_file_name(File), Line) @@ -117,7 +135,7 @@ class Remark(yaml.YAMLObject): def key(self): k = (self.__class__, self.PassWithDiffPrefix, self.Name, self.File, self.Line, self.Column, self.Function) for arg in self.Args: - for (key, value) in arg.iteritems(): + for (key, value) in iteritems(arg): if type(value) is dict: value = tuple(value.items()) k += (key, value) @@ -196,8 +214,8 @@ def gather_results(pmap, filenames): max_hotness = max(entry[0] for entry in remarks) def merge_file_remarks(file_remarks_job, all_remarks, merged): - for filename, d in file_remarks_job.iteritems(): - for line, remarks in d.iteritems(): + for filename, d in iteritems(file_remarks_job): + for line, remarks in iteritems(d): for remark in remarks: # Bring max_hotness into the remarks so that # RelativeHotness does not depend on an external global. diff --git a/utils/release/test-release.sh b/utils/release/test-release.sh index 560220cd53f4..8ec3abb17551 100755 --- a/utils/release/test-release.sh +++ b/utils/release/test-release.sh @@ -38,7 +38,7 @@ do_test_suite="yes" do_openmp="yes" do_lld="yes" do_lldb="no" -do_polly="no" +do_polly="yes" BuildDir="`pwd`" ExtraConfigureFlags="" ExportBranch="" @@ -68,8 +68,7 @@ function usage() { echo " -no-lld Disable check-out & build lld" echo " -lldb Enable check-out & build lldb" echo " -no-lldb Disable check-out & build lldb (default)" - echo " -polly Enable check-out & build Polly" - echo " -no-polly Disable check-out & build Polly (default)" + echo " -no-polly Disable check-out & build Polly" } while [ $# -gt 0 ]; do @@ -154,9 +153,6 @@ while [ $# -gt 0 ]; do -no-lldb ) do_lldb="no" ;; - -polly ) - do_polly="yes" - ;; -no-polly ) do_polly="no" ;; |