FunctionPassManager FPM;
FPM.addPass(PromotePass());auto m =FunctionAnalysisManager();auto b =PassBuilder();
b.registerFunctionAnalyses(m);
FPM.run(*fooFunc, m);
生成可obj.
#include"llvm/IR/IRBuilder.h"#include"llvm/IR/LLVMContext.h"#include"llvm/IR/Module.h"#include"llvm/IR/Verifier.h"#include"llvm/IR/LegacyPassManager.h"#include"llvm/ADT/APFloat.h"#include"llvm/ADT/STLExtras.h"#include"llvm/IR/BasicBlock.h"#include"llvm/IR/Constants.h"#include"llvm/IR/DerivedTypes.h"#include"llvm/IR/Function.h"#include"llvm/IR/IRBuilder.h"#include"llvm/IR/LLVMContext.h"#include"llvm/IR/LegacyPassManager.h"#include"llvm/IR/Module.h"#include"llvm/IR/Type.h"#include"llvm/IR/Verifier.h"#include"llvm/Support/TargetSelect.h"#include"llvm/Target/TargetMachine.h"#include"llvm/Transforms/InstCombine/InstCombine.h"#include"llvm/Transforms/Scalar.h"#include"llvm/Transforms/Scalar/GVN.h"#include"llvm/Transforms/Utils/Mem2Reg.h"#include"llvm/IR/PassManager.h"#include"llvm/Passes/PassBuilder.h"#include"llvm/IR/DIBuilder.h"#include"llvm/Target/TargetMachine.h"#include"llvm/Target/TargetOptions.h"#include"llvm/Support/TargetSelect.h"#include"llvm/TargetParser/Host.h"#include"llvm/MC/TargetRegistry.h"#include"llvm/Support/FileSystem.h"#include<string>#include<vector>usingnamespace std;usingnamespace llvm;static unique_ptr<LLVMContext> Context;// = new LLVMContext();static unique_ptr<Module> ModuleOb;static unique_ptr<IRBuilder<>> Builder;static std::unique_ptr<legacy::FunctionPassManager> TheFPM;classHello:publicFunctionPass{public:staticchar ID;Hello():FunctionPass(ID){}boolrunOnFunction(Function& F)override{errs()<<"Hello: ";errs().write_escaped(F.getName())<<'\n';returnfalse;}};// end of struct Hellochar Hello::ID =1010101;static RegisterPass<Hello>X("hello","Hello World Pass",false/* Only looks at CFG */,false/* Analysis Pass */);voidinit(){
Context =make_unique<LLVMContext>();
ModuleOb =make_unique<Module>("my compiler",*Context);
Builder =make_unique<IRBuilder<>>(*Context);
TheFPM = std::make_unique<legacy::FunctionPassManager>(ModuleOb.get());// Do simple "peephole" optimizations and bit-twiddling optzns.
TheFPM->add(createInstructionCombiningPass());// Reassociate expressions.
TheFPM->add(createReassociatePass());// Eliminate Common SubExpressions.
TheFPM->add(createGVNPass());// Simplify the control flow graph (deleting unreachable blocks, etc).
TheFPM->add(createCFGSimplificationPass());auto t =newHello();
TheFPM->add(t);
TheFPM->doInitialization();}
Function*createFunc(std::string Name){// Builder.reset();
std::vector<string> Args;
Args.push_back("a");
Args.push_back("b");
std::vector<Type*>Integers(Args.size(), Builder->getInt32Ty());
FunctionType* funcType =FunctionType::get(Builder->getInt32Ty(), Integers,false);
Function* fooFunc =Function::Create(funcType, Function::ExternalLinkage, Name,*ModuleOb);int idx =0;for(auto i = fooFunc->arg_begin(); i != fooFunc->arg_end(); i +=1){
i->setName(Args[idx++]);}auto entry =BasicBlock::Create(*Context,"entry", fooFunc);
Builder->SetInsertPoint(entry);
Value *sum=Builder->CreateMul(fooFunc->arg_begin(), fooFunc->arg_begin()+1,"sum");
Builder->CreateRet(sum);
fooFunc->setCallingConv(llvm::CallingConv::C);verifyFunction(*fooFunc);return fooFunc;}static std::unique_ptr<DIBuilder> DBuilder;intmain(){init();
Function* fooFunc =createFunc("mul");
ModuleOb->print(outs(),nullptr,false,false);auto TargetTriple = sys::getDefaultTargetTriple();InitializeAllTargetInfos();InitializeAllTargets();InitializeAllTargetMCs();InitializeAllAsmParsers();InitializeAllAsmPrinters();
std::string Error;auto Target =TargetRegistry::lookupTarget(TargetTriple, Error);// Print an error and exit if we couldn't find the requested target.// This generally occurs if we've forgotten to initialise the// TargetRegistry or we have a bogus target triple.if(!Target){errs()<< Error;return1;}auto CPU ="generic";auto Features ="";
TargetOptions opt;auto RM = std::optional<Reloc::Model>();auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
ModuleOb->setDataLayout(TargetMachine->createDataLayout());
ModuleOb->setTargetTriple(TargetTriple);
legacy::PassManager pass;auto Filename ="output.obj";
std::error_code EC;
raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);auto FileType = CGFT_ObjectFile;if(EC){errs()<<"Could not open file: "<< EC.message();return1;}if(TargetMachine->addPassesToEmitFile(pass, dest,nullptr, FileType)){errs()<<"TargetMachine can't emit a file of this type";return1;}
pass.run(*ModuleOb);
dest.flush();//ModuleOb->dump();}
int main() {
init();
auto val = (Constant::getIntegerValue(Builder->getInt64Ty(), APInt(64, 10, 10)));
auto t = llvm::ArrayType::get(Builder->getInt64Ty(), 100);
auto tt = llvm::ArrayType::get(t, 100);
auto func = createFunc(*Builder, "foo");
BasicBlock *entry = BasicBlock::Create(*TheContext, "entry",func);
Builder->SetInsertPoint(entry);
Builder->CreateAlloca(t);
Builder->CreateAlloca(tt);
func->print(outs());
}
初始化后端
int main() {
// Install standard binary operators.
// 1 is lowest precedence.
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
BinopPrecedence['*'] = 40; // highest.
// Prime the first token.
fprintf(stderr, "ready> ");
getNextToken();
InitializeModuleAndPassManager();
// Run the main "interpreter loop" now.
MainLoop();
// Initialize the target registry etc.
/*
InitializeAllTargetInfos();
InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmParsers();
InitializeAllAsmPrinters();
*/
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmParser();
LLVMInitializeX86AsmPrinter();
auto TargetTriple = sys::getDefaultTargetTriple();
TheModule->setTargetTriple(TargetTriple);
std::string Error;
auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);
// Print an error and exit if we couldn't find the requested target.
// This generally occurs if we've forgotten to initialise the
// TargetRegistry or we have a bogus target triple.
if (!Target) {
errs() << Error;
return 1;
}
auto CPU = "generic";
auto Features = "";
TargetOptions opt;
auto RM = std::optional<Reloc::Model>();
auto TheTargetMachine =
Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
TheModule->setDataLayout(TheTargetMachine->createDataLayout());
auto Filename = "output.o";
std::error_code EC;
raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);
if (EC) {
errs() << "Could not open file: " << EC.message();
return 1;
}
legacy::PassManager pass;
auto FileType = CGFT_ObjectFile;
if (TheTargetMachine->addPassesToEmitFile(pass, dest, nullptr, FileType)) {
errs() << "TheTargetMachine can't emit a file of this type";
return 1;
}
pass.run(*TheModule);
dest.flush();
outs() << "Wrote " << Filename << "\n";
return 0;
}