@@ -46,90 +46,22 @@ static cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
4646 cl::desc(" Output file" ),
4747 cl::sub(FromJSON));
4848
49- namespace {
50- // A structural representation of the JSON input.
51- struct DeserializableCtx {
52- GlobalValue::GUID Guid = 0 ;
53- std::vector<uint64_t > Counters;
54- std::vector<std::vector<DeserializableCtx>> Callsites;
55- };
56-
57- ctx_profile::ContextNode *
58- createNode (std::vector<std::unique_ptr<char []>> &Nodes,
59- const std::vector<DeserializableCtx> &DCList);
60-
61- // Convert a DeserializableCtx into a ContextNode, potentially linking it to
62- // its sibling (e.g. callee at same callsite) "Next".
63- ctx_profile::ContextNode *
64- createNode (std::vector<std::unique_ptr<char []>> &Nodes,
65- const DeserializableCtx &DC,
66- ctx_profile::ContextNode *Next = nullptr ) {
67- auto AllocSize = ctx_profile::ContextNode::getAllocSize (DC.Counters .size (),
68- DC.Callsites .size ());
69- auto *Mem = Nodes.emplace_back (std::make_unique<char []>(AllocSize)).get ();
70- std::memset (Mem, 0 , AllocSize);
71- auto *Ret = new (Mem) ctx_profile::ContextNode (DC.Guid , DC.Counters .size (),
72- DC.Callsites .size (), Next);
73- std::memcpy (Ret->counters (), DC.Counters .data (),
74- sizeof (uint64_t ) * DC.Counters .size ());
75- for (const auto &[I, DCList] : llvm::enumerate (DC.Callsites ))
76- Ret->subContexts ()[I] = createNode (Nodes, DCList);
77- return Ret;
78- }
79-
80- // Convert a list of DeserializableCtx into a linked list of ContextNodes.
81- ctx_profile::ContextNode *
82- createNode (std::vector<std::unique_ptr<char []>> &Nodes,
83- const std::vector<DeserializableCtx> &DCList) {
84- ctx_profile::ContextNode *List = nullptr ;
85- for (const auto &DC : DCList)
86- List = createNode (Nodes, DC, List);
87- return List;
88- }
89- } // namespace
90-
91- namespace llvm {
92- namespace json {
93- // Hook into the JSON deserialization.
94- bool fromJSON (const Value &E, DeserializableCtx &R, Path P) {
95- json::ObjectMapper Mapper (E, P);
96- return Mapper && Mapper.map (" Guid" , R.Guid ) &&
97- Mapper.map (" Counters" , R.Counters ) &&
98- Mapper.mapOptional (" Callsites" , R.Callsites );
99- }
100- } // namespace json
101- } // namespace llvm
102-
10349// Save the bitstream profile from the JSON representation.
10450Error convertFromJSON () {
10551 auto BufOrError = MemoryBuffer::getFileOrSTDIN (InputFilename);
10652 if (!BufOrError)
10753 return createFileError (InputFilename, BufOrError.getError ());
108- auto P = json::parse (BufOrError.get ()->getBuffer ());
109- if (!P)
110- return P.takeError ();
11154
112- std::vector<DeserializableCtx> DCList;
113- json::Path::Root R (" " );
114- if (!fromJSON (*P, DCList, R))
115- return R.getError ();
116- // Nodes provides memory backing for the ContextualNodes.
117- std::vector<std::unique_ptr<char []>> Nodes;
11855 std::error_code EC;
119- raw_fd_stream Out (OutputFilename, EC);
56+ // Using a fd_ostream instead of a fd_stream. The latter would be more
57+ // efficient as the bitstream writer supports incremental flush to it, but the
58+ // json scenario is for test, and file size scalability doesn't really concern
59+ // us.
60+ raw_fd_ostream Out (OutputFilename, EC);
12061 if (EC)
12162 return createStringError (EC, " failed to open output" );
122- PGOCtxProfileWriter Writer (Out);
123- for (const auto &DC : DCList) {
124- auto *TopList = createNode (Nodes, DC);
125- if (!TopList)
126- return createStringError (
127- " Unexpected error converting internal structure to ctx profile" );
128- Writer.write (*TopList);
129- }
130- if (EC)
131- return createStringError (EC, " failed to write output" );
132- return Error::success ();
63+
64+ return llvm::createCtxProfFromJSON (BufOrError.get ()->getBuffer (), Out);
13365}
13466
13567int main (int argc, const char **argv) {
0 commit comments