39 #include <llvm/ADT/Twine.h> 
   50                         bool Init, 
bool Cleanup) {
 
   51   OwningPtr<Transition> T(
new NullTransition(From, To, Init, Cleanup));
 
   52   Register(T, From, To, Transitions);
 
   60                                  Automaton.argument_size());
 
   62   OwningPtr<Transition> T(
new NowTransition(From, To, Ev, Refs, Init, Cleanup));
 
   63   Register(T, From, To, Transitions);
 
   70   OwningPtr<Transition> T(
 
   71     new FnTransition(From, To, Ev, Init, Cleanup, OutOfScope));
 
   73   Register(T, From, To, Transitions);
 
   80   OwningPtr<Transition> T(
 
   83   Register(T, From, To, Transitions);
 
   86 void Transition::CreateSubAutomaton(
State& From, 
State& To,
 
   91   Register(T, From, To, Transitions);
 
   97   OwningPtr<Transition> New;
 
  102   assert(!Init || !OutOfScope);
 
  111     auto O = cast<NowTransition>(Other);
 
  112     New.reset(
new NowTransition(From, To, O->Ev, O->Refs, Init, Cleanup));
 
  117     New.reset(
new FnTransition(From, To, cast<FnTransition>(Other)->Ev,
 
  118                                Init, Cleanup, OutOfScope));
 
  123                   From, To, cast<FieldAssignTransition>(Other)->Assign,
 
  124                   Init, Cleanup, OutOfScope));
 
  130                   cast<SubAutomatonTransition>(Other)->ID));
 
  135   Register(New, From, To, Transitions);
 
  138 void Transition::Register(OwningPtr<Transition>& T, 
State& From, 
State& To,
 
  141   Transitions.push_back(T.get());
 
  142   debugs(
"tesla.automata.transitions") << 
"registered " << T->String() << 
"\n";
 
  145   assert(To.
ID() != 0);
 
  156   auto& Out = 
debugs(
"tesla.automata.transitions.equivalence");
 
  157   Out << 
"grouping transitions:\n";
 
  159   for (
auto *T : Ungrouped) {
 
  160     Out << 
"  " << T->String() << 
"\n";
 
  162     bool FoundEquivalent = 
false;
 
  163     for (
auto& Set : EquivalenceClasses) {
 
  164       auto *Head = *Set.begin();
 
  165       if (T->EquivalentTo(*Head)) {
 
  166         assert(Head->EquivalentTo(*T));
 
  167         FoundEquivalent = 
true;
 
  173     if (!FoundEquivalent) {
 
  174       SmallPtrSet<const Transition*, 4> New;
 
  176       EquivalenceClasses.push_back(New);
 
  180   Out << 
"equivalence classes:\n";
 
  181   for (
auto& EquivClass : EquivalenceClasses) {
 
  184       Out << (Head ? 
"  " : 
"   == ") << T->String() << 
"\n";
 
  191 void Transition::ReferencesThusFar(OwningArrayPtr<const Argument*>& Args,
 
  195   SmallVector<const Argument*, 4> MyRefs;
 
  196   for (
auto Arg : this->Arguments())
 
  197     if (Arg && Arg->type() == Argument::Variable) {
 
  198       size_t i = Arg->index();
 
  200       if (MyRefs.size() <= i)
 
  201         MyRefs.resize(i + 1);
 
  206   auto& FromRefs = From.References();
 
  207   const size_t Size = FromRefs.size();
 
  209   auto Arguments = 
new const Argument*[Size];
 
  210   for (
size_t i = 0; i < Size; i++) {
 
  211     if ((MyRefs.size() > i) && MyRefs[i])
 
  212       Arguments[i] = MyRefs[i];
 
  214     else if ((FromRefs.size() > i) && FromRefs[i])
 
  215       Arguments[i] = FromRefs[i];
 
  221   Args.reset(Arguments);
 
  226 SmallVector<const Argument*,4> Transition::NewArguments()
 const {
 
  227   auto OldArgs(From.References());
 
  228   auto TransArgs(Arguments());
 
  230   SmallVector<const Argument*,4> NewArgs(TransArgs.size());
 
  231   for (
size_t i = 0; i < NewArgs.size(); i++)
 
  232     if ((OldArgs.size() <= i) || (OldArgs[i] == NULL))
 
  233       NewArgs[i] = TransArgs[i];
 
  239 int Transition::NewArgMask()
 const {
 
  240   auto NewArgs(NewArguments());
 
  243   for (
int i = 0; i < NewArgs.size(); i++)
 
  244     if ((NewArgs[i] != NULL) && (NewArgs[i]->type() == Argument::Variable))
 
  251 string Transition::String()
 const {
 
  253   for (
auto A : NewArguments())
 
  254     if ((A != NULL) && (A->type() == Argument::Variable))
 
  258     string(RequiresInit() ? 
"<<init>>" : 
"")
 
  259     + (RequiresCleanup() ? 
"<<cleanup>>" : 
"")
 
  265     + (NewArgs.empty() ? 
"" : 
":" + NewArgs)
 
  266     + (Special.empty() ? 
"" : 
" " + Special)
 
  275   const Argument* 
const *Args = Ev.argument().data();
 
  276   size_t Len = Ev.argument_size();
 
  281 string FnTransition::ShortLabel()
 const {
 
  282   std::stringstream ss;
 
  283   ss << Ev.function().name() << 
"(";
 
  285   for (
int i = 0; i < Ev.argument_size(); i++)
 
  288       << ((i < Ev.argument_size() - 1) ? 
"," : 
"");
 
  292   if (Ev.has_expectedreturnvalue()) {
 
  293     assert(Ev.direction() == FunctionEvent::Exit);
 
  294     ss << 
" == " << 
ShortName(&Ev.expectedreturnvalue());
 
  296     ss << 
": " << FunctionEvent::Direction_Name(Ev.direction());
 
  301 string FnTransition::DotLabel()
 const {
 
  302   std::stringstream ss;
 
  303   ss << Ev.function().name() << 
"(";
 
  305   for (
int i = 0; i < Ev.argument_size(); i++)
 
  308       << ((i < Ev.argument_size() - 1) ? 
"," : 
"");
 
  312   if (Ev.has_expectedreturnvalue()) {
 
  313     assert(Ev.direction() == FunctionEvent::Exit);
 
  314     ss << 
" == " << 
DotName(&Ev.expectedreturnvalue());
 
  317       << FunctionEvent::Direction_Name(Ev.direction())
 
  325 FieldAssignTransition::FieldAssignTransition(
const State& From, 
const State& To,
 
  327                                              bool Init, 
bool Cleanup,
 
  329   : 
Transition(From, To, Init, Cleanup, OutOfScope), Assign(A),
 
  330     ReferencedVariables(new const 
Argument*[2]),
 
  331     Refs(ReferencedVariables.get(), 2)
 
  333   ReferencedVariables[0] = &Assign.field().base();
 
  334   ReferencedVariables[1] = &Assign.value();
 
  351     + 
"struct " + Assign.
field().
type() + 
":\\l" 
  365   case FieldAssignment::PlusEqual:     
return "+=";