17d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===-- DiffConsumer.cpp - Difference Consumer ------------------*- C++ -*-===// 27d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// 37d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// The LLVM Compiler Infrastructure 47d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// 57d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// This file is distributed under the University of Illinois Open Source 67d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// License. See LICENSE.TXT for details. 77d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// 87d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===----------------------------------------------------------------------===// 97d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// 10c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru// This files implements the LLVM difference Consumer 117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// 127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===----------------------------------------------------------------------===// 137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 147d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "DiffConsumer.h" 150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 177d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "llvm/Support/ErrorHandling.h" 187d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 197d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinusing namespace llvm; 207d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 217d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinstatic void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering){ 227d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin unsigned IN = 0; 237d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 247d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin // Arguments get the first numbers. 257d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin for (Function::arg_iterator 267d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) 277d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (!AI->hasName()) 287d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Numbering[&*AI] = IN++; 297d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 307d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin // Walk the basic blocks in order. 317d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) { 327d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (!FI->hasName()) 337d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Numbering[&*FI] = IN++; 347d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 357d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin // Walk the instructions in order. 367d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) 377d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin // void instructions don't get numbers. 387d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (!BI->hasName() && !BI->getType()->isVoidTy()) 397d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Numbering[&*BI] = IN++; 407d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 417d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 427d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin assert(!Numbering.empty() && "asked for numbering but numbering was no-op"); 437d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 447d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 457d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 462d24e2a396a1d211baaeedf32148a3b657240170David Blaikievoid Consumer::anchor() { } 472d24e2a396a1d211baaeedf32148a3b657240170David Blaikie 487d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::printValue(Value *V, bool isL) { 497d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (V->hasName()) { 507d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << (isa<GlobalValue>(V) ? '@' : '%') << V->getName(); 517d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin return; 527d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 537d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (V->getType()->isVoidTy()) { 547d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (isa<StoreInst>(V)) { 557d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "store to "; 567d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(cast<StoreInst>(V)->getPointerOperand(), isL); 577d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } else if (isa<CallInst>(V)) { 587d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "call to "; 597d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(cast<CallInst>(V)->getCalledValue(), isL); 607d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } else if (isa<InvokeInst>(V)) { 617d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "invoke to "; 627d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(cast<InvokeInst>(V)->getCalledValue(), isL); 637d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } else { 647d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << *V; 657d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 667d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin return; 677d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 68fd22883a345b2e04d0bdb4d4b9ed64ceebdc0601John McCall if (isa<Constant>(V)) { 69bd3c5ecd37e760f0430c9cbd1fda5740eb7c0e27John McCall out << *V; 70bd3c5ecd37e760f0430c9cbd1fda5740eb7c0e27John McCall return; 71bd3c5ecd37e760f0430c9cbd1fda5740eb7c0e27John McCall } 727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 737d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin unsigned N = contexts.size(); 747d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin while (N > 0) { 757d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin --N; 767d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin DiffContext &ctxt = contexts[N]; 777d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (!ctxt.IsFunction) continue; 787d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (isL) { 797d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (ctxt.LNumbering.empty()) 807d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin ComputeNumbering(cast<Function>(ctxt.L), ctxt.LNumbering); 817d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << '%' << ctxt.LNumbering[V]; 827d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin return; 837d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } else { 847d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (ctxt.RNumbering.empty()) 857d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin ComputeNumbering(cast<Function>(ctxt.R), ctxt.RNumbering); 867d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << '%' << ctxt.RNumbering[V]; 877d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin return; 887d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 897d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 907d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 917d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "<anonymous>"; 927d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 937d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 947d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::header() { 957d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (contexts.empty()) return; 967d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin for (SmallVectorImpl<DiffContext>::iterator 977d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin I = contexts.begin(), E = contexts.end(); I != E; ++I) { 987d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (I->Differences) continue; 997d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (isa<Function>(I->L)) { 1007d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin // Extra newline between functions. 1017d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (Differences) out << "\n"; 1027d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1037d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Function *L = cast<Function>(I->L); 1047d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Function *R = cast<Function>(I->R); 1057d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (L->getName() != R->getName()) 1067d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "in function " << L->getName() 1077d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin << " / " << R->getName() << ":\n"; 1087d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin else 1097d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "in function " << L->getName() << ":\n"; 1107d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } else if (isa<BasicBlock>(I->L)) { 1117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin BasicBlock *L = cast<BasicBlock>(I->L); 1127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin BasicBlock *R = cast<BasicBlock>(I->R); 1137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (L->hasName() && R->hasName() && L->getName() == R->getName()) 1147d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << " in block %" << L->getName() << ":\n"; 1157d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin else { 1167d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << " in block "; 1177d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(L, true); 1187d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << " / "; 1197d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(R, false); 1207d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << ":\n"; 1217d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 1227d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } else if (isa<Instruction>(I->L)) { 1237d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << " in instruction "; 1247d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(I->L, true); 1257d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << " / "; 1267d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin printValue(I->R, false); 1277d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << ":\n"; 1287d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 1297d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1307d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin I->Differences = true; 1317d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 1327d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1337d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1347d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::indent() { 1357d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin unsigned N = Indent; 1367d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin while (N--) out << ' '; 1377d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1387d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1397d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinbool DiffConsumer::hadDifferences() const { 1407d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin return Differences; 1417d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1427d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1437d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::enterContext(Value *L, Value *R) { 1447d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin contexts.push_back(DiffContext(L, R)); 1457d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Indent += 2; 1467d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1477d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1487d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::exitContext() { 1497d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Differences |= contexts.back().Differences; 1507d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin contexts.pop_back(); 1517d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Indent -= 2; 1527d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1537d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1547d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::log(StringRef text) { 1557d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin header(); 1567d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin indent(); 1577d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << text << '\n'; 1587d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1597d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1607d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::logf(const LogBuilder &Log) { 1617d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin header(); 1627d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin indent(); 1637d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1647d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin unsigned arg = 0; 1657d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1667d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin StringRef format = Log.getFormat(); 1677d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin while (true) { 1687d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin size_t percent = format.find('%'); 1697d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (percent == StringRef::npos) { 1707d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << format; 1717d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin break; 1727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 1737d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin assert(format[percent] == '%'); 1747d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1757d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin if (percent > 0) out << format.substr(0, percent); 1767d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1777d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin switch (format[percent+1]) { 1787d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin case '%': out << '%'; break; 1797d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin case 'l': printValue(Log.getArgument(arg++), true); break; 1807d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin case 'r': printValue(Log.getArgument(arg++), false); break; 1817d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin default: llvm_unreachable("unknown format character"); 1827d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 1837d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1847d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin format = format.substr(percent+2); 1857d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 1867d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1877d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << '\n'; 1887d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 1897d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1907d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinvoid DiffConsumer::logd(const DiffLogBuilder &Log) { 1917d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin header(); 1927d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin 1937d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) { 1947d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin indent(); 1957d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin switch (Log.getLineKind(I)) { 1967d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin case DC_match: 1977d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << " "; 1987d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Log.getLeft(I)->dump(); 1997d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin //printValue(Log.getLeft(I), true); 2007d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin break; 2017d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin case DC_left: 2027d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "< "; 2037d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Log.getLeft(I)->dump(); 2047d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin //printValue(Log.getLeft(I), true); 2057d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin break; 2067d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin case DC_right: 2077d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin out << "> "; 2087d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin Log.getRight(I)->dump(); 2097d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin //printValue(Log.getRight(I), false); 2107d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin break; 2117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 2127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin //out << "\n"; 2137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin } 2147d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin} 215