diff --git a/include/llvm/CodeGen/PMLExport.h b/include/llvm/CodeGen/PMLExport.h index 417c2b78f82fe934ee41b4b047e75ae80674f858..7f6988e616bd469cfe43d4206ebe51dde64e077d 100644 --- a/include/llvm/CodeGen/PMLExport.h +++ b/include/llvm/CodeGen/PMLExport.h @@ -104,6 +104,9 @@ namespace llvm { yaml::FlowFact *createLoopFact(const BasicBlock *BB, yaml::Name RHS, bool UserAnnot = false) const; + yaml::PlatinaFact *createPlatinaGuardFact(const BasicBlock *BB, + const StringRef& expr) const; + public: PMLBitcodeExport(TargetMachine &TM, ModulePass &mp) : YDoc(TM.getTargetTriple().getTriple()), P(mp) {} diff --git a/include/llvm/PML.h b/include/llvm/PML.h index 4a390b14bffb22b87ed457ce974eafb5f8df3a4c..fc3c5c600697b385cb49c65526e0321e48fd19a4 100644 --- a/include/llvm/PML.h +++ b/include/llvm/PML.h @@ -933,6 +933,54 @@ struct MappingTraits< FlowFact* > { YAML_IS_PTR_SEQUENCE_VECTOR(FlowFact) +/// Representation Level (source, bitcode, machinecode) +enum PlatinaType { unknown, guard }; +template <> +struct ScalarEnumerationTraits<PlatinaType> { + static void enumeration(IO &io, PlatinaType& level) { + io.enumCase(level, "guard", guard); + io.enumCase(level, "unknown", unknown); + } +}; + +struct PlatinaFact { + Name Origin; + ReprLevel Level; + PlatinaType Type; + ProgramPoint* Loc; + Name Expr; + + PlatinaFact(ReprLevel lvl) : Level(lvl), Type(unknown), Loc(nullptr) {} + ~PlatinaFact() { + if (Loc) delete Loc; + } + + void setLocation(ProgramPoint *PP) { + if (Loc) delete Loc; + Loc = nullptr; + if (PP) + Loc = new ProgramPoint(*PP); + } + +private: + PlatinaFact(const PlatinaFact&); // Disable copy constructor + PlatinaFact* operator=(const PlatinaFact&); // Disable assignment + +}; +template <> +struct MappingTraits< PlatinaFact* > { + static void mapping(IO &io, PlatinaFact *&PF) { + if (!PF) PF = new PlatinaFact(level_bitcode); + io.mapRequired("program-point", PF->Loc); + io.mapRequired("origin", PF->Origin); + io.mapRequired("level", PF->Level); + io.mapRequired("type", PF->Type); + io.mapRequired("expression", PF->Expr); + } +}; + +YAML_IS_PTR_SEQUENCE_VECTOR(PlatinaFact) + // Timing ////////////////////////////////////////////////////////////////////////////// @@ -1021,9 +1069,10 @@ struct PMLDoc { std::vector<BitcodeFunction*> BitcodeFunctions; std::vector<MachineFunction*> MachineFunctions; std::vector<RelationGraph*> RelationGraphs; - std::vector<FlowFact*> FlowFacts; - std::vector<ValueFact*> ValueFacts; - std::vector<Timing*> Timings; + std::vector<FlowFact*> FlowFacts; + std::vector<ValueFact*> ValueFacts; + std::vector<Timing*> Timings; + std::vector<PlatinaFact*> PlatinaFacts; PMLDoc() : FormatVersion("pml-0.1"), TargetTriple("") {} @@ -1039,6 +1088,7 @@ struct PMLDoc { DELETE_PTR_VEC(ValueFacts); DELETE_PTR_VEC(FlowFacts); DELETE_PTR_VEC(Timings); + DELETE_PTR_VEC(PlatinaFacts); } /// Add a function, which is owned by the document afterwards void addFunction(BitcodeFunction *F) { @@ -1061,10 +1111,15 @@ struct PMLDoc { FlowFacts.push_back(FF); } + /// Add a flowfact, which is owned by the document afterwards + void addPlatinaFact(PlatinaFact* PF) { + PlatinaFacts.push_back(PF); + } + bool empty() { return BitcodeFunctions.empty() && MachineFunctions.empty() && RelationGraphs.empty() && ValueFacts.empty() && - FlowFacts.empty() && Timings.empty(); + FlowFacts.empty() && Timings.empty() && PlatinaFacts.empty(); } /// Merge another PML doc into this one, transferring ownership of all childs. @@ -1097,6 +1152,10 @@ struct PMLDoc { Doc.Timings.begin(), Doc.Timings.end()); Doc.Timings.clear(); + PlatinaFacts.insert(PlatinaFacts.end(), + Doc.PlatinaFacts.begin(), + Doc.PlatinaFacts.end()); + Doc.PlatinaFacts.clear(); } private: @@ -1107,14 +1166,15 @@ template <> struct MappingTraits< PMLDoc* > { static void mapping(IO &io, PMLDoc *&doc) { if (!doc) doc = new PMLDoc(); - io.mapRequired("format", doc->FormatVersion); - io.mapRequired("triple", doc->TargetTriple); - io.mapOptional("bitcode-functions",doc->BitcodeFunctions); - io.mapOptional("machine-functions",doc->MachineFunctions); - io.mapOptional("relation-graphs",doc->RelationGraphs); - io.mapOptional("flowfacts", doc->FlowFacts); - io.mapOptional("valuefacts", doc->ValueFacts); - io.mapOptional("timing", doc->Timings); + io.mapRequired("format", doc->FormatVersion); + io.mapRequired("triple", doc->TargetTriple); + io.mapOptional("bitcode-functions", doc->BitcodeFunctions); + io.mapOptional("machine-functions", doc->MachineFunctions); + io.mapOptional("relation-graphs", doc->RelationGraphs); + io.mapOptional("flowfacts", doc->FlowFacts); + io.mapOptional("valuefacts", doc->ValueFacts); + io.mapOptional("timing", doc->Timings); + io.mapOptional("modelfacts", doc->PlatinaFacts); } }; diff --git a/lib/CodeGen/PMLExport.cpp b/lib/CodeGen/PMLExport.cpp index ddfad173a784af951ae0a260089fea9f3ebe22b0..0ebc95015e4f9d0fe0842c5af220bee22a139801 100644 --- a/lib/CodeGen/PMLExport.cpp +++ b/lib/CodeGen/PMLExport.cpp @@ -227,6 +227,23 @@ yaml::FlowFact *PMLBitcodeExport::createLoopFact(const BasicBlock *BB, return FF; } +yaml::PlatinaFact *PMLBitcodeExport::createPlatinaGuardFact(const BasicBlock *BB, + const StringRef& expr) const { + const Function *Fn = BB->getParent(); + + yaml::PlatinaFact *PF = new yaml::PlatinaFact(yaml::level_bitcode); + + PF->setLocation(yaml::ProgramPoint::CreateBlock(Fn->getName(), + BB->getName() + )); + + PF->Expr = yaml::Name(expr); + PF->Origin = "platina.bc"; + PF->Type = yaml::guard; + + return PF; +} + void PMLBitcodeExport::serialize(MachineFunction &MF) { const Function *Fn = MF.getFunction(); @@ -394,8 +411,9 @@ void PMLBitcodeExport::exportInstruction(yaml::Instruction* I, break; case Intrinsic::platina: { + const BasicBlock *BB = II->getParent(); MDString *expr = cast<MDString>(CI->getMetadata("platina.guardexpr")->getOperand(0)); - errs() << "[Platina]: " << expr->getString() << "\n"; + YDoc.addPlatinaFact(createPlatinaGuardFact(&*BB, expr->getString())); } break; default: