4 #include <llvm/ADT/StringRef.h>
5 #include <llvm/ADT/SmallVector.h>
6 #include <llvm/ADT/DenseMap.h>
8 // Required to parse .ll files.
9 #include <llvm/Support/SourceMgr.h>
10 #include <llvm/Assembly/Parser.h>
12 // Required to parse .bc files.
13 #include <llvm/Support/MemoryBuffer.h>
14 #include <llvm/Bitcode/ReaderWriter.h>
16 #include <llvm/Support/raw_ostream.h>
17 #include <llvm/LLVMContext.h>
18 #include <llvm/Module.h>
19 #include <llvm/Type.h>
20 #include <llvm/Instructions.h>
22 #include "DifferenceEngine.h"
26 /// Reads a module from a file. If the filename ends in .ll, it is
27 /// interpreted as an assembly file; otherwise, it is interpreted as
28 /// bitcode. On error, messages are written to stderr and null is
30 static Module *ReadModule(LLVMContext &Context, StringRef Name) {
31 // LLVM assembly path.
32 if (Name.endswith(".ll")) {
34 Module *M = ParseAssemblyFile(Name, Diag, Context);
37 Diag.Print("llvmdiff", errs());
42 MemoryBuffer *Buffer = MemoryBuffer::getFile(Name);
44 // ParseBitcodeFile takes ownership of the buffer if it succeeds.
46 Module *M = ParseBitcodeFile(Buffer, Context, &Error);
49 errs() << "error parsing " << Name << ": " << Error;
55 errs() << "expected usage:\n";
56 errs() << " llvm-diff oldmodule.ll newmodule.ll [function list]\n";
57 errs() << "Assembly or bitcode modules may be used interchangeably.\n";
58 errs() << "If no functions are provided, all functions will be compared.\n";
64 DiffContext(Value *L, Value *R)
65 : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
70 DenseMap<Value*,unsigned> LNumbering;
71 DenseMap<Value*,unsigned> RNumbering;
74 void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering) {
78 // Arguments get the first numbers.
79 for (Function::arg_iterator
80 AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI)
82 Numbering[&*AI] = IN++;
84 // Walk the basic blocks in order.
85 for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
86 // Basic blocks have their own 'namespace'.
88 Numbering[&*FI] = BBN++;
90 // Walk the instructions in order.
91 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
92 // void instructions don't get numbers.
93 if (!BI->hasName() && !BI->getType()->isVoidTy())
94 Numbering[&*BI] = IN++;
97 assert(!Numbering.empty() && "asked for numbering but numbering was no-op");
100 class DiffConsumer : public DifferenceEngine::Consumer {
104 SmallVector<DiffContext, 5> contexts;
108 void printValue(Value *V, bool isL) {
110 errs() << (isa<GlobalValue>(V) ? '@' : '%') << V->getName();
113 if (V->getType()->isVoidTy()) {
114 if (isa<StoreInst>(V)) {
115 errs() << "store to ";
116 printValue(cast<StoreInst>(V)->getPointerOperand(), isL);
117 } else if (isa<CallInst>(V)) {
118 errs() << "call to ";
119 printValue(cast<CallInst>(V)->getCalledValue(), isL);
120 } else if (isa<InvokeInst>(V)) {
121 errs() << "invoke to ";
122 printValue(cast<InvokeInst>(V)->getCalledValue(), isL);
129 unsigned N = contexts.size();
132 DiffContext &ctxt = contexts[N];
133 if (!ctxt.IsFunction) continue;
135 if (ctxt.LNumbering.empty())
136 ComputeNumbering(cast<Function>(ctxt.L), ctxt.LNumbering);
137 errs() << '%' << ctxt.LNumbering[V];
140 if (ctxt.RNumbering.empty())
141 ComputeNumbering(cast<Function>(ctxt.R), ctxt.RNumbering);
142 errs() << '%' << ctxt.RNumbering[V];
147 errs() << "<anonymous>";
151 if (contexts.empty()) return;
152 for (SmallVectorImpl<DiffContext>::iterator
153 I = contexts.begin(), E = contexts.end(); I != E; ++I) {
154 if (I->Differences) continue;
155 if (isa<Function>(I->L)) {
156 // Extra newline between functions.
157 if (Differences) errs() << "\n";
159 Function *L = cast<Function>(I->L);
160 Function *R = cast<Function>(I->R);
161 if (L->getName() != R->getName())
162 errs() << "in function " << L->getName() << " / " << R->getName() << ":\n";
164 errs() << "in function " << L->getName() << ":\n";
165 } else if (isa<BasicBlock>(I->L)) {
166 BasicBlock *L = cast<BasicBlock>(I->L);
167 BasicBlock *R = cast<BasicBlock>(I->R);
168 errs() << " in block ";
171 printValue(R, false);
173 } else if (isa<Instruction>(I->L)) {
174 errs() << " in instruction ";
175 printValue(I->L, true);
177 printValue(I->R, false);
181 I->Differences = true;
187 while (N--) errs() << ' ';
191 DiffConsumer(Module *L, Module *R)
192 : LModule(L), RModule(R), Differences(false), Indent(0) {}
194 bool hadDifferences() const { return Differences; }
196 void enterContext(Value *L, Value *R) {
197 contexts.push_back(DiffContext(L, R));
201 Differences |= contexts.back().Differences;
206 void log(StringRef text) {
209 errs() << text << "\n";
212 void logf(const DifferenceEngine::LogBuilder &Log) {
216 // FIXME: we don't know whether these are l-values or r-values (ha!)
217 // Print them in some saner way!
218 errs() << Log.getFormat() << "\n";
219 for (unsigned I = 0, E = Log.getNumArguments(); I != E; ++I)
220 Log.getArgument(I)->dump();
223 void logd(const DifferenceEngine::DiffLogBuilder &Log) {
226 for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) {
228 switch (Log.getLineKind(I)) {
229 case DifferenceEngine::DC_match:
231 Log.getLeft(I)->dump();
232 //printValue(Log.getLeft(I), true);
234 case DifferenceEngine::DC_left:
236 Log.getLeft(I)->dump();
237 //printValue(Log.getLeft(I), true);
239 case DifferenceEngine::DC_right:
241 Log.getRight(I)->dump();
242 //printValue(Log.getRight(I), false);
252 int main(int argc, const char **argv) {
253 if (argc < 3) return usage();
255 // Don't make StringRef locals like this at home.
256 StringRef LModuleFile = argv[1];
257 StringRef RModuleFile = argv[2];
261 // Load both modules. Die if that fails.
262 Module *LModule = ReadModule(Context, LModuleFile);
263 Module *RModule = ReadModule(Context, RModuleFile);
264 if (!LModule || !RModule) return 1;
266 DiffConsumer Consumer(LModule, RModule);
267 DifferenceEngine Engine(Context, Consumer);
269 // If any function names were given, just diff those.
270 const char **FnNames = argv + 3;
271 unsigned NumFnNames = argc - 3;
273 for (unsigned I = 0; I != NumFnNames; ++I) {
274 StringRef FnName = FnNames[I];
276 // Drop leading sigils from the function name.
277 if (FnName.startswith("@")) FnName = FnName.substr(1);
279 Function *LFn = LModule->getFunction(FnName);
280 Function *RFn = RModule->getFunction(FnName);
282 Engine.diff(LFn, RFn);
285 errs() << "No function named @" << FnName << " in either module\n";
287 errs() << "No function named @" << FnName << " in left module\n";
289 errs() << "No function named @" << FnName << " in right module\n";
293 // Otherwise, diff all functions in the modules.
294 Engine.diff(LModule, RModule);
300 return Consumer.hadDifferences();