22
22
// ===----------------------------------------------------------------------===//
23
23
24
24
#include " CodeRegion.h"
25
+ #include " CodeRegionGenerator.h"
25
26
#include " PipelinePrinter.h"
26
27
#include " Stages/FetchStage.h"
27
28
#include " Stages/InstructionTables.h"
39
40
#include " llvm/MC/MCAsmInfo.h"
40
41
#include " llvm/MC/MCContext.h"
41
42
#include " llvm/MC/MCObjectFileInfo.h"
42
- #include " llvm/MC/MCParser/MCTargetAsmParser.h"
43
43
#include " llvm/MC/MCRegisterInfo.h"
44
- #include " llvm/MC/MCStreamer.h"
45
44
#include " llvm/Support/CommandLine.h"
46
45
#include " llvm/Support/ErrorHandling.h"
47
46
#include " llvm/Support/ErrorOr.h"
@@ -199,59 +198,6 @@ const Target *getTarget(const char *ProgName) {
199
198
return TheTarget;
200
199
}
201
200
202
- // A comment consumer that parses strings.
203
- // The only valid tokens are strings.
204
- class MCACommentConsumer : public AsmCommentConsumer {
205
- public:
206
- mca::CodeRegions &Regions;
207
-
208
- MCACommentConsumer (mca::CodeRegions &R) : Regions(R) {}
209
- void HandleComment (SMLoc Loc, StringRef CommentText) override {
210
- // Skip empty comments.
211
- StringRef Comment (CommentText);
212
- if (Comment.empty ())
213
- return ;
214
-
215
- // Skip spaces and tabs
216
- unsigned Position = Comment.find_first_not_of (" \t " );
217
- if (Position >= Comment.size ())
218
- // We reached the end of the comment. Bail out.
219
- return ;
220
-
221
- Comment = Comment.drop_front (Position);
222
- if (Comment.consume_front (" LLVM-MCA-END" )) {
223
- Regions.endRegion (Loc);
224
- return ;
225
- }
226
-
227
- // Now try to parse string LLVM-MCA-BEGIN
228
- if (!Comment.consume_front (" LLVM-MCA-BEGIN" ))
229
- return ;
230
-
231
- // Skip spaces and tabs
232
- Position = Comment.find_first_not_of (" \t " );
233
- if (Position < Comment.size ())
234
- Comment = Comment.drop_front (Position);
235
- // Use the rest of the string as a descriptor for this code snippet.
236
- Regions.beginRegion (Comment, Loc);
237
- }
238
- };
239
-
240
- int AssembleInput (MCAsmParser &Parser, const Target *TheTarget,
241
- MCSubtargetInfo &STI, MCInstrInfo &MCII,
242
- MCTargetOptions &MCOptions) {
243
- std::unique_ptr<MCTargetAsmParser> TAP (
244
- TheTarget->createMCAsmParser (STI, Parser, MCII, MCOptions));
245
-
246
- if (!TAP) {
247
- WithColor::error () << " this target does not support assembly parsing.\n " ;
248
- return 1 ;
249
- }
250
-
251
- Parser.setTargetParser (*TAP);
252
- return Parser.Run (false );
253
- }
254
-
255
201
ErrorOr<std::unique_ptr<ToolOutputFile>> getOutputStream () {
256
202
if (OutputFilename == " " )
257
203
OutputFilename = " -" ;
@@ -262,40 +208,6 @@ ErrorOr<std::unique_ptr<ToolOutputFile>> getOutputStream() {
262
208
return std::move (Out);
263
209
return EC;
264
210
}
265
-
266
- class MCStreamerWrapper final : public MCStreamer {
267
- mca::CodeRegions &Regions;
268
-
269
- public:
270
- MCStreamerWrapper (MCContext &Context, mca::CodeRegions &R)
271
- : MCStreamer(Context), Regions(R) {}
272
-
273
- // We only want to intercept the emission of new instructions.
274
- virtual void EmitInstruction (const MCInst &Inst,
275
- const MCSubtargetInfo & /* unused */ ,
276
- bool /* unused */ ) override {
277
- Regions.addInstruction (Inst);
278
- }
279
-
280
- bool EmitSymbolAttribute (MCSymbol *Symbol, MCSymbolAttr Attribute) override {
281
- return true ;
282
- }
283
-
284
- void EmitCommonSymbol (MCSymbol *Symbol, uint64_t Size ,
285
- unsigned ByteAlignment) override {}
286
- void EmitZerofill (MCSection *Section, MCSymbol *Symbol = nullptr ,
287
- uint64_t Size = 0 , unsigned ByteAlignment = 0 ,
288
- SMLoc Loc = SMLoc()) override {}
289
- void EmitGPRel32Value (const MCExpr *Value) override {}
290
- void BeginCOFFSymbolDef (const MCSymbol *Symbol) override {}
291
- void EmitCOFFSymbolStorageClass (int StorageClass) override {}
292
- void EmitCOFFSymbolType (int Type) override {}
293
- void EndCOFFSymbolDef () override {}
294
-
295
- ArrayRef<MCInst> GetInstructionSequence (unsigned Index) const {
296
- return Regions.getInstructionSequence (Index);
297
- }
298
- };
299
211
} // end of anonymous namespace
300
212
301
213
static void processOptionImpl (cl::opt<bool > &O, const cl::opt<bool > &Default) {
@@ -352,9 +264,6 @@ int main(int argc, char **argv) {
352
264
cl::ParseCommandLineOptions (argc, argv,
353
265
" llvm machine code performance analyzer.\n " );
354
266
355
- MCTargetOptions MCOptions;
356
- MCOptions.PreserveAsmComments = false ;
357
-
358
267
// Get the target from the triple. If a triple is not specified, then select
359
268
// the default triple for the host. If the triple doesn't correspond to any
360
269
// registered target, then exit with an error message.
@@ -394,9 +303,6 @@ int main(int argc, char **argv) {
394
303
395
304
std::unique_ptr<buffer_ostream> BOS;
396
305
397
- mca::CodeRegions Regions (SrcMgr);
398
- MCStreamerWrapper Str (Ctx, Regions);
399
-
400
306
std::unique_ptr<MCInstrInfo> MCII (TheTarget->createMCInstrInfo ());
401
307
402
308
std::unique_ptr<MCInstrAnalysis> MCIA (
@@ -429,14 +335,14 @@ int main(int argc, char **argv) {
429
335
return 1 ;
430
336
}
431
337
432
- std::unique_ptr<MCAsmParser> P (createMCAsmParser (SrcMgr, Ctx, Str, *MAI));
433
- MCAsmLexer &Lexer = P->getLexer ();
434
- MCACommentConsumer CC (Regions);
435
- Lexer.setCommentConsumer (&CC);
436
-
437
- if (AssembleInput (*P, TheTarget, *STI, *MCII, MCOptions))
338
+ // Parse the input and create CodeRegions that llvm-mca can analyze.
339
+ mca::AsmCodeRegionGenerator CRG (*TheTarget, SrcMgr, Ctx, *MAI, *STI, *MCII);
340
+ Expected<const mca::CodeRegions &> RegionsOrErr = CRG.parseCodeRegions ();
341
+ if (auto Err = RegionsOrErr.takeError ()) {
342
+ WithColor::error () << Err << " \n " ;
438
343
return 1 ;
439
-
344
+ }
345
+ const mca::CodeRegions &Regions = *RegionsOrErr;
440
346
if (Regions.empty ()) {
441
347
WithColor::error () << " no assembly instructions found.\n " ;
442
348
return 1 ;
@@ -449,7 +355,7 @@ int main(int argc, char **argv) {
449
355
return 1 ;
450
356
}
451
357
452
- unsigned AssemblerDialect = P-> getAssemblerDialect ();
358
+ unsigned AssemblerDialect = CRG. getAssemblerDialect ();
453
359
if (OutputAsmVariant >= 0 )
454
360
AssemblerDialect = static_cast <unsigned >(OutputAsmVariant);
455
361
std::unique_ptr<MCInstPrinter> IP (TheTarget->createMCInstPrinter (
0 commit comments