Skip to content

Commit

Permalink
Reland [clang-fuzzer] Use new pass manager for optimizing IR
Browse files Browse the repository at this point in the history
With CMakeLists.txt fix.
  • Loading branch information
aeubanks committed Nov 24, 2022
1 parent 5cc6963 commit 66b1f6b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 39 deletions.
1 change: 1 addition & 0 deletions clang/tools/clang-fuzzer/handle-llvm/CMakeLists.txt
Expand Up @@ -8,6 +8,7 @@ set(LLVM_LINK_COMPONENTS
MC
MCJIT
Object
Passes
RuntimeDyld
SelectionDAG
Support
Expand Down
87 changes: 48 additions & 39 deletions clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
Expand Up @@ -30,34 +30,28 @@
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Pass.h"
#include "llvm/PassRegistry.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Vectorize.h"

using namespace llvm;

static codegen::RegisterCodeGenFlags CGF;

// Define a type for the functions that are compiled and executed
typedef void (*LLVMFunc)(int*, int*, int*, int);

// Helper function to parse command line args and find the optimization level
static void getOptLevel(const std::vector<const char *> &ExtraArgs,
CodeGenOpt::Level &OLvl) {
static CodeGenOpt::Level
getOptLevel(const std::vector<const char *> &ExtraArgs) {
// Find the optimization level from the command line args
OLvl = CodeGenOpt::Default;
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
for (auto &A : ExtraArgs) {
if (A[0] == '-' && A[1] == 'O') {
switch(A[2]) {
Expand All @@ -71,6 +65,7 @@ static void getOptLevel(const std::vector<const char *> &ExtraArgs,
}
}
}
return OLvl;
}

static void ErrorAndExit(std::string message) {
Expand All @@ -80,16 +75,45 @@ static void ErrorAndExit(std::string message) {

// Helper function to add optimization passes to the TargetMachine at the
// specified optimization level, OptLevel
static void AddOptimizationPasses(legacy::PassManagerBase &MPM,
CodeGenOpt::Level OptLevel,
unsigned SizeLevel) {
// Create and initialize a PassManagerBuilder
PassManagerBuilder Builder;
Builder.OptLevel = OptLevel;
Builder.SizeLevel = SizeLevel;
Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel, false);
Builder.LoopVectorize = true;
Builder.populateModulePassManager(MPM);
static void RunOptimizationPasses(raw_ostream &OS, Module &M,
CodeGenOpt::Level OptLevel) {
llvm::OptimizationLevel OL;
switch (OptLevel) {
case CodeGenOpt::None:
OL = OptimizationLevel::O0;
break;
case CodeGenOpt::Less:
OL = OptimizationLevel::O1;
break;
case CodeGenOpt::Default:
OL = OptimizationLevel::O2;
break;
case CodeGenOpt::Aggressive:
OL = OptimizationLevel::O3;
break;
}

LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
CGSCCAnalysisManager CGAM;
ModuleAnalysisManager MAM;

PassBuilder PB;

PB.registerModuleAnalyses(MAM);
PB.registerCGSCCAnalyses(CGAM);
PB.registerFunctionAnalyses(FAM);
PB.registerLoopAnalyses(LAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);

ModulePassManager MPM;
if (OL == OptimizationLevel::O0)
MPM = PB.buildO0DefaultPipeline(OL);
else
MPM = PB.buildPerModuleDefaultPipeline(OL);
MPM.addPass(PrintModulePass(OS));

MPM.run(M, MAM);
}

// Mimics the opt tool to run an optimization pass over the provided IR
Expand Down Expand Up @@ -120,24 +144,10 @@ static std::string OptLLVM(const std::string &IR, CodeGenOpt::Level OLvl) {
codegen::setFunctionAttributes(codegen::getCPUStr(),
codegen::getFeaturesStr(), *M);

legacy::PassManager Passes;

Passes.add(new TargetLibraryInfoWrapperPass(ModuleTriple));
Passes.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));

LLVMTargetMachine &LTM = static_cast<LLVMTargetMachine &>(*TM);
Passes.add(LTM.createPassConfig(Passes));

Passes.add(createVerifierPass());

AddOptimizationPasses(Passes, OLvl, 0);

// Add a pass that writes the optimized IR to an output stream
std::string outString;
raw_string_ostream OS(outString);
Passes.add(createPrintModulePass(OS, "", false));

Passes.run(*M);
RunOptimizationPasses(OS, *M, OLvl);

return outString;
}
Expand Down Expand Up @@ -216,8 +226,7 @@ void clang_fuzzer::HandleLLVM(const std::string &IR,
memcpy(UnoptArrays, InputArrays, kTotalSize);

// Parse ExtraArgs to set the optimization level
CodeGenOpt::Level OLvl;
getOptLevel(ExtraArgs, OLvl);
CodeGenOpt::Level OLvl = getOptLevel(ExtraArgs);

// First we optimize the IR by running a loop vectorizer pass
std::string OptIR = OptLLVM(IR, OLvl);
Expand Down

0 comments on commit 66b1f6b

Please sign in to comment.