vector<Value*> AssertionSiteInstrumenter::CollectArgs( Instruction *Before, const Automaton& A, Module& Mod, IRBuilder<>& Builder) { // Find named values to be passed to instrumentation. std::map<string,Value*> ValuesInScope; for (auto G = Mod.global_begin(); G != Mod.global_end(); G++) ValuesInScope[G->getName()] = G; auto *Fn = Before->getParent()->getParent(); for (auto& Arg : Fn->getArgumentList()) ValuesInScope[Arg.getName()] = &Arg; auto& EntryBlock(*Fn->begin()); for (auto& I : EntryBlock) { auto *Inst = dyn_cast<AllocaInst>(&I); if (!Inst) break; ValuesInScope[Inst->getName()] = Builder.CreateLoad(Inst); } int ArgSize = 0; for (auto& Arg : A.getAssertion().argument()) if (!Arg.free()) ArgSize = std::max(ArgSize + 1, Arg.index()); vector<Value*> Args(ArgSize, NULL); for (auto& Arg : A.getAssertion().argument()) { if (Arg.free()) continue; string Name(BaseName(Arg)); if (ValuesInScope.find(Name) == ValuesInScope.end()) { string s; raw_string_ostream Out(s); for (auto v : ValuesInScope) { Out << " \"" << v.first << "\": "; v.second->getType()->print(Out); Out << "\n"; } panic("assertion references non-existent variable '" + BaseName(Arg) + "'; was it defined under '#ifdef TESLA'?\n\n" "Variables in scope are:\n" + Out.str()); } Args[Arg.index()] = GetArgumentValue(ValuesInScope[Name], Arg, Builder, true); } return Args; }
void EventTranslator::CallUpdateState(const Automaton& A, uint32_t Symbol) { std::vector<Value*> Args; Args.push_back(InstrCtx.TeslaContext(A.getAssertion().context())); Args.push_back(InstrCtx.ExternalDescription(A)); Args.push_back(ConstantInt::get(InstrCtx.Int32Ty, Symbol)); Args.push_back(Key); Builder.CreateCall(InstrCtx.UpdateStateFn(), Args); }