xref: /aosp_15_r20/external/llvm/tools/llvm-diff/llvm-diff.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- llvm-diff.cpp - Module comparator command-line driver ---*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines the command-line driver for the difference engine.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "DiffLog.h"
15*9880d681SAndroid Build Coastguard Worker #include "DifferenceEngine.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IRReader/IRReader.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
25*9880d681SAndroid Build Coastguard Worker #include <string>
26*9880d681SAndroid Build Coastguard Worker #include <utility>
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker /// Reads a module from a file.  On error, messages are written to stderr
32*9880d681SAndroid Build Coastguard Worker /// and null is returned.
readModule(LLVMContext & Context,StringRef Name)33*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<Module> readModule(LLVMContext &Context,
34*9880d681SAndroid Build Coastguard Worker                                           StringRef Name) {
35*9880d681SAndroid Build Coastguard Worker   SMDiagnostic Diag;
36*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<Module> M = parseIRFile(Name, Diag, Context);
37*9880d681SAndroid Build Coastguard Worker   if (!M)
38*9880d681SAndroid Build Coastguard Worker     Diag.print("llvm-diff", errs());
39*9880d681SAndroid Build Coastguard Worker   return M;
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker 
diffGlobal(DifferenceEngine & Engine,Module & L,Module & R,StringRef Name)42*9880d681SAndroid Build Coastguard Worker static void diffGlobal(DifferenceEngine &Engine, Module &L, Module &R,
43*9880d681SAndroid Build Coastguard Worker                        StringRef Name) {
44*9880d681SAndroid Build Coastguard Worker   // Drop leading sigils from the global name.
45*9880d681SAndroid Build Coastguard Worker   if (Name.startswith("@")) Name = Name.substr(1);
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker   Function *LFn = L.getFunction(Name);
48*9880d681SAndroid Build Coastguard Worker   Function *RFn = R.getFunction(Name);
49*9880d681SAndroid Build Coastguard Worker   if (LFn && RFn)
50*9880d681SAndroid Build Coastguard Worker     Engine.diff(LFn, RFn);
51*9880d681SAndroid Build Coastguard Worker   else if (!LFn && !RFn)
52*9880d681SAndroid Build Coastguard Worker     errs() << "No function named @" << Name << " in either module\n";
53*9880d681SAndroid Build Coastguard Worker   else if (!LFn)
54*9880d681SAndroid Build Coastguard Worker     errs() << "No function named @" << Name << " in left module\n";
55*9880d681SAndroid Build Coastguard Worker   else
56*9880d681SAndroid Build Coastguard Worker     errs() << "No function named @" << Name << " in right module\n";
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string> LeftFilename(cl::Positional,
60*9880d681SAndroid Build Coastguard Worker                                          cl::desc("<first file>"),
61*9880d681SAndroid Build Coastguard Worker                                          cl::Required);
62*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string> RightFilename(cl::Positional,
63*9880d681SAndroid Build Coastguard Worker                                           cl::desc("<second file>"),
64*9880d681SAndroid Build Coastguard Worker                                           cl::Required);
65*9880d681SAndroid Build Coastguard Worker static cl::list<std::string> GlobalsToCompare(cl::Positional,
66*9880d681SAndroid Build Coastguard Worker                                               cl::desc("<globals to compare>"));
67*9880d681SAndroid Build Coastguard Worker 
main(int argc,char ** argv)68*9880d681SAndroid Build Coastguard Worker int main(int argc, char **argv) {
69*9880d681SAndroid Build Coastguard Worker   cl::ParseCommandLineOptions(argc, argv);
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   LLVMContext Context;
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker   // Load both modules.  Die if that fails.
74*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<Module> LModule = readModule(Context, LeftFilename);
75*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<Module> RModule = readModule(Context, RightFilename);
76*9880d681SAndroid Build Coastguard Worker   if (!LModule || !RModule) return 1;
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker   DiffConsumer Consumer;
79*9880d681SAndroid Build Coastguard Worker   DifferenceEngine Engine(Consumer);
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker   // If any global names were given, just diff those.
82*9880d681SAndroid Build Coastguard Worker   if (!GlobalsToCompare.empty()) {
83*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0, E = GlobalsToCompare.size(); I != E; ++I)
84*9880d681SAndroid Build Coastguard Worker       diffGlobal(Engine, *LModule, *RModule, GlobalsToCompare[I]);
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   // Otherwise, diff everything in the module.
87*9880d681SAndroid Build Coastguard Worker   } else {
88*9880d681SAndroid Build Coastguard Worker     Engine.diff(LModule.get(), RModule.get());
89*9880d681SAndroid Build Coastguard Worker   }
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker   return Consumer.hadDifferences();
92*9880d681SAndroid Build Coastguard Worker }
93