llvm-dis.cpp revision 9bff2e952226a80b65a993a81e87abe5216ffc48
1009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===------------------------------------------------------------------------=== 2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// LLVM 'DIS' UTILITY 3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This utility may be invoked in the following manner: 5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// dis [options] - Read LLVM bytecode from stdin, write assembly to stdout 6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// dis [options] x.bc - Read LLVM bytecode from the x.bc file, write assembly 7009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// to the x.ll file. 89bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// Options: 99bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// --help - Output information about command line switches 109bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// -dfo - Print basic blocks in depth first order 119bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// -rdfo - Print basic blocks in reverse depth first order 129bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// -po - Print basic blocks in post order 139bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// -rpo - Print basic blocks in reverse post order 149bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// 159bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// TODO: add -vcg which prints VCG compatible output. 16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 17009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===------------------------------------------------------------------------=== 18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 19009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include <iostream.h> 20009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include <fstream.h> 21009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h" 22009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Assembly/Writer.h" 23009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Bytecode/Reader.h" 24009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Tools/CommandLine.h" 259bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner#include "llvm/Method.h" 269bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner#include "llvm/CFG.h" 27009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 28009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerint main(int argc, char **argv) { 299bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner // WriteMode - The different orderings to print basic blocks in... 309bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner enum { 319bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner Default = 0, // Method Order (list order) 329bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner DepthFirst, // Depth First ordering 339bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner ReverseDepthFirst, // Reverse Depth First ordering 349bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner PostOrder, // Post Order 359bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner ReversePostOrder // Reverse Post Order 369bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } WriteMode = Default; 379bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner 38009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ToolCommandLine Opts(argc, argv, false); 39009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 40009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // We only support the options that the system parser does... if it left any 41009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // then we don't know what to do. 42009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // 43009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (argc > 1) { 44009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner for (int i = 1; i < argc; i++) { 459bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner if (string(argv[i]) == string("--help")) { 469bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner cerr << argv[0] << " usage:\n" 479bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\tx.bc - Parse <x.bc> file and output to x.ll\n" 489bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\tno .bc file - Parse stdin and write to stdout.\n" 499bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\t-dfo - Write basic blocks in depth first order.\n" 509bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\t-rdfo - Write basic blocks in reverse DFO.\n" 519bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\t-po - Write basic blocks in postorder.\n" 529bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\t-rpo - Write basic blocks in reverse postorder.\n" 539bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner << "\t--help - Print this usage information\n\n"; 549bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner return 1; 559bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } else if (string(argv[i]) == string("-dfo")) { 569bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner WriteMode = DepthFirst; 579bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } else if (string(argv[i]) == string("-rdfo")) { 589bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner WriteMode = ReverseDepthFirst; 599bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } else if (string(argv[i]) == string("-po")) { 609bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner WriteMode = PostOrder; 619bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } else if (string(argv[i]) == string("-rpo")) { 629bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner WriteMode = ReversePostOrder; 639bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } else { 64009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner cerr << argv[0] << ": argument not recognized: '" << argv[i] << "'!\n"; 659bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } 66009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 67009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 68009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 69009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ostream *Out = &cout; // Default to printing to stdout... 70009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 71009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Module *C = ParseBytecodeFile(Opts.getInputFilename()); 72009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (C == 0) { 73009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner cerr << "bytecode didn't read correctly.\n"; 74009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 1; 75009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 76009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 77009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Opts.getOutputFilename() != "-") { 78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out = new ofstream(Opts.getOutputFilename().c_str(), 79009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner (Opts.getForce() ? 0 : ios::noreplace)|ios::out); 80009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (!Out->good()) { 81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner cerr << "Error opening " << Opts.getOutputFilename() 82009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner << ": sending to stdout instead!\n"; 83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out = &cout; 84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 86009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 87009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // All that dis does is write the assembly out to a file... which is exactly 88009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // what the writer library is supposed to do... 899bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner // 909bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner if (WriteMode == Default) { 919bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner (*Out) << C; // Print out in list order 929bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } else { 939bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner // TODO: This does not print anything other than the basic blocks in the 949bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner // methods... more should definately be printed. It should be valid output 959bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner // consumable by the assembler. 969bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner // 979bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner for (Module::MethodListType::iterator I = C->getMethodList().begin(); 989bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner I != C->getMethodList().end(); I++) { 999bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner Method *M = *I; 1009bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner (*Out) << "-------------- Method: " << M->getName() << " -------------\n"; 1019bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner 1029bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner switch (WriteMode) { 1039bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner case DepthFirst: // Depth First ordering 1049bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner copy(cfg::df_begin(M), cfg::df_end(M), 1059bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner ostream_iterator<BasicBlock*>(*Out, "\n")); 1069bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner break; 1079bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner case ReverseDepthFirst: // Reverse Depth First ordering 1089bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner copy(cfg::df_begin(M, true), cfg::df_end(M), 1099bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner ostream_iterator<BasicBlock*>(*Out, "\n")); 1109bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner break; 1119bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner case PostOrder: // Post Order 1129bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner copy(cfg::po_begin(M), cfg::po_end(M), 1139bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner ostream_iterator<BasicBlock*>(*Out, "\n")); 1149bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner break; 1159bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner case ReversePostOrder: { // Reverse Post Order 1169bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner cfg::ReversePostOrderTraversal RPOT(M); 1179bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner copy(RPOT.begin(), RPOT.end(), 1189bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner ostream_iterator<BasicBlock*>(*Out, "\n")); 1199bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner break; 1209bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } 1219bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner default: 1229bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner abort(); 1239bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner break; 1249bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } 1259bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } 1269bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } 127009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner delete C; 128009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 129009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Out != &cout) delete Out; 130009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 0; 131009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 132