llvm.org GIT mirror llvm / 2906355
Add new edge property combinator: weight. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50765 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Glushenkov 11 years ago
3 changed file(s) with 102 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
5252 def if_input_languages_contain;
5353
5454 // Edge property combinators.
55 def weight;
5556 def and;
5657 def or;
5758
7677
7778 class Edge : EdgeBase;
7879
79 // Edge and DefaultEdge are synonyms.
80 class DefaultEdge : EdgeBase;
80 // Edge and SimpleEdge are synonyms.
81 class SimpleEdge : EdgeBase;
8182
8283 // Optionally enabled edge.
8384 class OptionalEdge lst> : EdgeBase;
119119 language belongs to the current input language set.
120120
121121 - ``and`` - Edge property combinator. Returns true if all of its
122 arguments return true. Used like this: (and
123 (prop1), (prop2), ... (propN)). Nesting not allowed.
122 arguments return true. Used like this: ``(and (prop1), (prop2),
123 ... (propN))``. Nesting is allowed, but not encouraged.
124124
125125 - ``or`` - Edge property combinator that returns true if any one of its
126 arguments returns true. Example: (or (prop1), (prop2), ... (propN))
126 arguments returns true. Example: ``(or (prop1), (prop2), ... (propN))``.
127
128 - ``weight`` - Makes it possible to explicitly specify the quantity
129 added to the edge weight if this edge property matches. Used like
130 this: ``(weight N, (prop))``. The inner property can include
131 ``and`` and ``or`` combinators. When N is equal to 2, equivalent
132 to ``(prop)``.
133
134 Example: ``(weight 8, (and (switch_on "a"), (switch_on "b")))``.
135
127136
128137 To get a visual representation of the compilation graph (useful for
129138 debugging), run ``llvmc2 --view-graph``. You will need ``dot`` and
5656 StringInit& val = dynamic_cast(*ptr);
5757 return val.getValue();
5858 }
59
60 int InitPtrToInt(Init* ptr) {
61 IntInit& val = dynamic_cast(*ptr);
62 return val.getValue();
63 }
64
65 const DagInit& InitPtrToDagInitRef(Init* ptr) {
66 DagInit& val = dynamic_cast(*ptr);
67 return val;
68 }
69
5970
6071 // Ensure that the number of args in d is <= min_arguments,
6172 // throw exception otherwise
309320
310321 // "Property handler" - a function that extracts information
311322 // about a given tool property from its DAG representation
312 typedef void (CollectProperties::*PropertyHandler)(DagInit*);
323 typedef void (CollectProperties::*PropertyHandler)(const DagInit*);
313324
314325 // Map from property names -> property handlers
315326 typedef StringMap PropertyHandlerMap;
316327
317328 // "Option property handler" - a function that extracts information
318329 // about a given option property from its DAG representation
319 typedef void (CollectProperties::*
320 OptionPropertyHandler)(DagInit*, GlobalOptionDescription &);
330 typedef void (CollectProperties::* OptionPropertyHandler)
331 (const DagInit*, GlobalOptionDescription &);
321332
322333 // Map from option property names -> option property handlers
323334 typedef StringMap OptionPropertyHandlerMap;
374385 // Gets called for every tool property;
375386 // Just forwards to the corresponding property handler.
376387 void operator() (Init* i) {
377 DagInit& d = dynamic_cast(*i);
388 const DagInit& d = InitPtrToDagInitRef(i);
378389 const std::string& property_name = d.getOperator()->getAsString();
379390 PropertyHandlerMap::iterator method
380391 = propertyHandlers_.find(property_name);
394405 /// Functions that extract information about tool properties from
395406 /// DAG representation.
396407
397 void onCmdLine (DagInit* d) {
408 void onCmdLine (const DagInit* d) {
398409 checkNumberOfArguments(d, 1);
399410 SplitString(InitPtrToString(d->getArg(0)), toolProps_.CmdLine);
400411 if (toolProps_.CmdLine.empty())
401412 throw "Tool " + toolProps_.Name + " has empty command line!";
402413 }
403414
404 void onInLanguage (DagInit* d) {
415 void onInLanguage (const DagInit* d) {
405416 checkNumberOfArguments(d, 1);
406417 toolProps_.InLanguage = InitPtrToString(d->getArg(0));
407418 }
408419
409 void onJoin (DagInit* d) {
420 void onJoin (const DagInit* d) {
410421 checkNumberOfArguments(d, 0);
411422 toolProps_.setJoin();
412423 }
413424
414 void onOutLanguage (DagInit* d) {
425 void onOutLanguage (const DagInit* d) {
415426 checkNumberOfArguments(d, 1);
416427 toolProps_.OutLanguage = InitPtrToString(d->getArg(0));
417428 }
418429
419 void onOutputSuffix (DagInit* d) {
430 void onOutputSuffix (const DagInit* d) {
420431 checkNumberOfArguments(d, 1);
421432 toolProps_.OutputSuffix = InitPtrToString(d->getArg(0));
422433 }
423434
424 void onSink (DagInit* d) {
435 void onSink (const DagInit* d) {
425436 checkNumberOfArguments(d, 0);
426437 optDescs_.HasSink = true;
427438 toolProps_.setSink();
428439 }
429440
430 void onSwitch (DagInit* d) { addOption(d, OptionType::Switch); }
431 void onParameter (DagInit* d) { addOption(d, OptionType::Parameter); }
432 void onParameterList (DagInit* d) { addOption(d, OptionType::ParameterList); }
433 void onPrefix (DagInit* d) { addOption(d, OptionType::Prefix); }
434 void onPrefixList (DagInit* d) { addOption(d, OptionType::PrefixList); }
441 void onSwitch (const DagInit* d) {
442 addOption(d, OptionType::Switch);
443 }
444
445 void onParameter (const DagInit* d) {
446 addOption(d, OptionType::Parameter);
447 }
448
449 void onParameterList (const DagInit* d) {
450 addOption(d, OptionType::ParameterList);
451 }
452
453 void onPrefix (const DagInit* d) {
454 addOption(d, OptionType::Prefix);
455 }
456
457 void onPrefixList (const DagInit* d) {
458 addOption(d, OptionType::PrefixList);
459 }
435460
436461 /// Option property handlers --
437462 /// Methods that handle properties that are common for all types of
438463 /// options (like append_cmd, stop_compilation)
439464
440 void onAppendCmd (DagInit* d, GlobalOptionDescription& o) {
465 void onAppendCmd (const DagInit* d, GlobalOptionDescription& o) {
441466 checkNumberOfArguments(d, 1);
442467 std::string const& cmd = InitPtrToString(d->getArg(0));
443468
444469 toolProps_.OptDescs[o.Name].AddProperty(OptionPropertyType::AppendCmd, cmd);
445470 }
446471
447 void onForward (DagInit* d, GlobalOptionDescription& o) {
472 void onForward (const DagInit* d, GlobalOptionDescription& o) {
448473 checkNumberOfArguments(d, 0);
449474 toolProps_.OptDescs[o.Name].setForward();
450475 }
451476
452 void onHelp (DagInit* d, GlobalOptionDescription& o) {
477 void onHelp (const DagInit* d, GlobalOptionDescription& o) {
453478 checkNumberOfArguments(d, 1);
454479 const std::string& help_message = InitPtrToString(d->getArg(0));
455480
456481 o.Help = help_message;
457482 }
458483
459 void onRequired (DagInit* d, GlobalOptionDescription& o) {
484 void onRequired (const DagInit* d, GlobalOptionDescription& o) {
460485 checkNumberOfArguments(d, 0);
461486 o.setRequired();
462487 }
463488
464 void onStopCompilation (DagInit* d, GlobalOptionDescription& o) {
489 void onStopCompilation (const DagInit* d, GlobalOptionDescription& o) {
465490 checkNumberOfArguments(d, 0);
466491 if (o.Type != OptionType::Switch)
467492 throw std::string("Only options of type Switch can stop compilation!");
468493 toolProps_.OptDescs[o.Name].setStopCompilation();
469494 }
470495
471 void onUnpackValues (DagInit* d, GlobalOptionDescription& o) {
496 void onUnpackValues (const DagInit* d, GlobalOptionDescription& o) {
472497 checkNumberOfArguments(d, 0);
473498 toolProps_.OptDescs[o.Name].setUnpackValues();
474499 }
476501 /// Helper functions
477502
478503 // Add an option of type t
479 void addOption (DagInit* d, OptionType::OptionType t) {
504 void addOption (const DagInit* d, OptionType::OptionType t) {
480505 checkNumberOfArguments(d, 2);
481506 const std::string& name = InitPtrToString(d->getArg(0));
482507
505530 // Parameters:
506531 // name - option name
507532 // d - option property list
508 void processOptionProperties (DagInit* d, GlobalOptionDescription& o) {
533 void processOptionProperties (const DagInit* d, GlobalOptionDescription& o) {
509534 // First argument is option name
510535 checkNumberOfArguments(d, 2);
511536
512537 for (unsigned B = 1, E = d->getNumArgs(); B!=E; ++B) {
513 DagInit& option_property
514 = dynamic_cast(*d->getArg(B));
538 const DagInit& option_property
539 = InitPtrToDagInitRef(d->getArg(B));
515540 const std::string& option_property_name
516541 = option_property.getOperator()->getAsString();
517542 OptionPropertyHandlerMap::iterator method
962987 return false;
963988 }
964989
965 // Helper function used by EmitEdgeClass.
966 void EmitEdgePropertyTest(const std::string& PropName,
967 const DagInit& Prop,
990 // Forward declaration.
991 void EmitEdgePropertyTest(const DagInit& Prop,
968992 const GlobalOptionDescriptions& OptDescs,
969 std::ostream& O) {
970 if (EmitEdgePropertyTest1Arg(PropName, Prop, OptDescs, O))
971 return;
972 else if (EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O))
973 return;
974 else
975 throw PropName + ": unknown edge property!";
976 }
993 std::ostream& O);
977994
978995 // Helper function used by EmitEdgeClass.
979996 void EmitLogicalOperationTest(const DagInit& Prop, const char* LogicOp,
981998 std::ostream& O) {
982999 O << '(';
9831000 for (unsigned j = 0, NumArgs = Prop.getNumArgs(); j < NumArgs; ++j) {
984 const DagInit& InnerProp = dynamic_cast(*Prop.getArg(j));
985 const std::string& InnerPropName =
986 InnerProp.getOperator()->getAsString();
987 EmitEdgePropertyTest(InnerPropName, InnerProp, OptDescs, O);
1001 const DagInit& InnerProp = InitPtrToDagInitRef(Prop.getArg(j));
1002 EmitEdgePropertyTest(InnerProp, OptDescs, O);
9881003 if (j != NumArgs - 1)
9891004 O << ")\n" << Indent3 << ' ' << LogicOp << " (";
9901005 else
9921007 }
9931008 }
9941009
1010 // Helper function used by EmitEdgeClass.
1011 void EmitEdgePropertyTest(const DagInit& Prop,
1012 const GlobalOptionDescriptions& OptDescs,
1013 std::ostream& O) {
1014 const std::string& PropName = Prop.getOperator()->getAsString();
1015
1016 if (PropName == "and")
1017 EmitLogicalOperationTest(Prop, "&&", OptDescs, O);
1018 else if (PropName == "or")
1019 EmitLogicalOperationTest(Prop, "||", OptDescs, O);
1020 else if (EmitEdgePropertyTest1Arg(PropName, Prop, OptDescs, O))
1021 return;
1022 else if (EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O))
1023 return;
1024 else
1025 throw PropName + ": unknown edge property!";
1026 }
1027
9951028 // Emit a single Edge* class.
9961029 void EmitEdgeClass(unsigned N, const std::string& Target,
9971030 ListInit* Props, const GlobalOptionDescriptions& OptDescs,
9981031 std::ostream& O) {
999 bool IsDefault = false;
10001032
10011033 // Class constructor.
10021034 O << "class Edge" << N << ": public Edge {\n"
10081040 << Indent1 << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n"
10091041 << Indent2 << "unsigned ret = 0;\n";
10101042
1043 // Emit tests for every edge property.
10111044 for (size_t i = 0, PropsSize = Props->size(); i < PropsSize; ++i) {
1012 const DagInit& Prop = dynamic_cast(*Props->getElement(i));
1045 const DagInit& Prop = InitPtrToDagInitRef(Props->getElement(i));
10131046 const std::string& PropName = Prop.getOperator()->getAsString();
1014
1015 if (PropName == "default")
1016 IsDefault = true;
1047 unsigned N = 2;
10171048
10181049 O << Indent2 << "if (";
1019 if (PropName == "and") {
1020 EmitLogicalOperationTest(Prop, "&&", OptDescs, O);
1021 }
1022 else if (PropName == "or") {
1023 EmitLogicalOperationTest(Prop, "||", OptDescs, O);
1050
1051 if (PropName == "weight") {
1052 checkNumberOfArguments(&Prop, 2);
1053 N = InitPtrToInt(Prop.getArg(0));
1054 const DagInit& InnerProp = InitPtrToDagInitRef(Prop.getArg(1));
1055 EmitEdgePropertyTest(InnerProp, OptDescs, O);
10241056 }
10251057 else {
1026 EmitEdgePropertyTest(PropName, Prop, OptDescs, O);
1027 }
1028 O << ")\n" << Indent3 << "ret += 2;\n";
1029 }
1030
1031 if (IsDefault)
1032 O << Indent2 << "ret += 1;\n";
1058 EmitEdgePropertyTest(Prop, OptDescs, O);
1059 }
1060
1061 O << ")\n" << Indent3 << "ret += " << N << ";\n";
1062 }
10331063
10341064 O << Indent2 << "return ret;\n"
10351065 << Indent1 << "};\n\n};\n\n";