Commit dcbaea45 authored by Naman Dixit's avatar Naman Dixit

Implemented all the features

parent 031ca77f
......@@ -48,9 +48,9 @@ LanguageFlags="--std=c++17 -DBUILD_INTERNAL -DBUILD_SLOW -DBUILD_DEBUG -D_GNU_SO
-D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE \
"
WarningFlags="-Weverything -Wpedantic -pedantic-errors -Werror \
-Wno-c++98-compat \
-Wno-c++98-compat -Wno-padded \
"
LinkerFlags="-static-libgcc -pthread -ldl $(llvm-config-13 --ldflags --libs) -lncurses \
LinkerFlags="-rdynamic -static-libgcc -pthread -ldl $(llvm-config-13 --ldflags --libs) -lncurses \
-lclangFrontendTool -lclangFrontend -lclangDriver -lclangSerialization -lclangCodeGen \
-lclangParse -lclangSema -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers \
-lclangStaticAnalyzerCore -lclangAnalysis -lclangARCMigrate -lclangRewriteFrontend \
......
/*
* Creator: Naman Dixit
* Notice: © Copyright 2022 Naman Dixit
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow-field-in-constructor"
namespace {
using namespace llvm;
using namespace orc;
class GazelleJIT {
private:
std::unique_ptr<ExecutionSession> ES;
DataLayout DL;
MangleAndInterner Mangle;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer CompileLayer;
JITDylib &MainJD;
public:
GazelleJIT(std::unique_ptr<ExecutionSession> ES,
JITTargetMachineBuilder JTMB, DataLayout DL)
: ES(std::move(ES)), DL(std::move(DL)), Mangle(*this->ES, this->DL),
ObjectLayer(*this->ES,
[]() { return std::make_unique<SectionMemoryManager>(); }),
CompileLayer(*this->ES, ObjectLayer,
std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),
MainJD(this->ES->createBareJITDylib("<main>")) {
MainJD.addGenerator(
cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
DL.getGlobalPrefix())));
}
~GazelleJIT() {
if (auto Err = ES->endSession())
ES->reportError(std::move(Err));
}
static Expected<std::unique_ptr<GazelleJIT>> Create() {
auto EPC = SelfExecutorProcessControl::Create();
if (!EPC)
return EPC.takeError();
auto ES = std::make_unique<ExecutionSession>(std::move(*EPC));
JITTargetMachineBuilder JTMB(
ES->getExecutorProcessControl().getTargetTriple());
auto DL = JTMB.getDefaultDataLayoutForTarget();
if (!DL)
return DL.takeError();
return std::make_unique<GazelleJIT>(std::move(ES), std::move(JTMB),
std::move(*DL));
}
const DataLayout &getDataLayout() const { return DL; }
JITDylib &getMainJITDylib() { return MainJD; }
Error addModule(ThreadSafeModule TSM, ResourceTrackerSP RT = nullptr) {
if (!RT)
RT = MainJD.getDefaultResourceTracker();
return CompileLayer.add(RT, std::move(TSM));
}
Expected<JITEvaluatedSymbol> lookup(StringRef Name) {
return ES->lookup({&MainJD}, Mangle(Name.str()));
}
};
}
#pragma clang diagnostic pop
......@@ -9,6 +9,26 @@
#include <string>
#include <vector>
extern "C" {
void external (void);
void external (void) {
std::cout << "External function loaded from JIT" << std::endl;
}
void yield (void);
void yield (void) {
std::cout << "----yield()-----" << std::endl;
}
void overloaded_outside (void);
void overloaded_outside (void)
{
printf("OUTSIDE OUTSIDE\n");
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wunused-parameter"
......@@ -49,6 +69,7 @@
#include <llvm/ADT/StringExtras.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Analysis/LoopInfo.h>
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/CodeGen/CommandFlags.h>
#include <llvm/CodeGen/LinkAllCodegenComponents.h>
......@@ -59,11 +80,15 @@
#include <llvm/ExecutionEngine/JITSymbol.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/ObjectCache.h>
#include <llvm/ExecutionEngine/Orc/CompileUtils.h>
#include <llvm/ExecutionEngine/Orc/Core.h>
#include <llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h>
#include <llvm/ExecutionEngine/Orc/DebugUtils.h>
#include <llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h>
#include <llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h>
#include <llvm/ExecutionEngine/Orc/ExecutionUtils.h>
#include <llvm/ExecutionEngine/Orc/ExecutorProcessControl.h>
#include <llvm/ExecutionEngine/Orc/IRCompileLayer.h>
#include <llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h>
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
#include <llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h>
......@@ -73,7 +98,10 @@
#include <llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h>
#include <llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Type.h>
......@@ -81,6 +109,7 @@
#include <llvm/IRReader/IRReader.h>
#include <llvm/Object/Archive.h>
#include <llvm/Object/ObjectFile.h>
#include <llvm/Pass.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/DynamicLibrary.h>
......@@ -99,6 +128,9 @@
#include <llvm/Support/WithColor.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Transforms/Instrumentation.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <llvm/Transforms/Utils/BasicBlockUtils.h>
#include <llvm/Transforms/Utils/Cloning.h>
#include <llvm/IR/AssemblyAnnotationWriter.h>
#include <clang/Lex/PreprocessorOptions.h>
......@@ -110,17 +142,115 @@
#pragma clang diagnostic pop
#include "jit.cpp"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
static llvm::codegen::RegisterCodeGenFlags CGF;
static llvm::ExitOnError ExitOnErr;
static std::unique_ptr<llvm::LLVMContext> Context;
static std::unique_ptr<GazelleJIT> jit;
static std::unique_ptr<llvm::legacy::FunctionPassManager> TheFPM;
#pragma clang diagnostic pop
int demo2 (int x);
int demo2 (int x) {
return x * 2;
namespace {
struct FuncModifier : public llvm::FunctionPass {
static char ID;
FuncModifier () : llvm::FunctionPass (ID) {}
void loopRecursion (Loop *L, Module *module) {
BasicBlock *BB = L->getHeader();
llvm::BasicBlock::iterator BI = BB->begin();
llvm::Function* func = module->getFunction("yield");
if (func == nullptr) {
llvm::Type *void_type = Type::getPrimitiveType (*Context, llvm::Type::VoidTyID);
llvm::FunctionType *func_type = FunctionType::get(void_type, false);
func = Function::Create(func_type, GlobalValue::ExternalLinkage,
"yield", module);
func->setCallingConv(CallingConv::C);
}
llvm::Instruction *newInst = CallInst::Create(func);
// if (newInst == nullptr) std::cout << "newInst==NULL" << std::endl;
// (void)newInst;
BB->getInstList().insert(BI, newInst);
std::vector<Loop*> subLoops = L->getSubLoops();
for (Loop::iterator j = subLoops.begin(), f = subLoops.end(); j != f; ++j)
loopRecursion(*j, module);
}
bool runOnFunction (llvm::Function &F) override {
// llvm::errs() << "FuncName: ";
// llvm::errs().write_escaped(F.getName()) << '\n';
llvm::Module* module = F.getParent();
{ // Instering Yield on Function start
llvm::Function::iterator BB = F.begin();
llvm::BasicBlock::iterator BI = BB->begin();
llvm::Function* func = module->getFunction("yield");
if (func == nullptr) {
llvm::Type *void_type = Type::getPrimitiveType (*Context, llvm::Type::VoidTyID);
llvm::FunctionType *func_type = FunctionType::get(void_type, false);
func = Function::Create(func_type, GlobalValue::ExternalLinkage,
"yield", module);
func->setCallingConv(CallingConv::C);
}
llvm::Instruction *newInst = CallInst::Create(func);
// if (newInst == nullptr) std::cout << "newInst==NULL" << std::endl;
// (void)newInst;
BB->getInstList().insert(BI, newInst);
}
{ // Inserting yields on loop start
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) {
loopRecursion(*i, module);
}
}
{ // Replacing functions
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) {
if (isa<CallBase>(&(*BI))) {
Function* func = cast<CallBase>(*BI).getCalledFunction();
StringRef func_name_ref = func->getName();
std::string func_name = func_name_ref.str();
if (func_name == "overloaded_inside") {
std::cout << "Found inside" << std::endl;
llvm::Function* func_out = module->getFunction("overloaded_outside");
if (func_out == nullptr) {
llvm::Type *void_type = Type::getPrimitiveType(*Context, llvm::Type::VoidTyID);
llvm::FunctionType *func_out_type = FunctionType::get(void_type, false);
func_out = Function::Create(func_out_type, GlobalValue::ExternalLinkage,
"overloaded_outside", module);
func_out->setCallingConv(CallingConv::C);
}
// cast<CallBase>(*BI).setCalledFunction(func_out);
llvm::Instruction *newInst = CallInst::Create(func_out);
llvm::ReplaceInstWithInst(BB->getInstList(), BI, newInst);
}
}
}
}
}
return true;
}
virtual void getAnalysisUsage(AnalysisUsage& AU) const override {
AU.addRequired<LoopInfoWrapperPass>();
}
};
}
char FuncModifier::ID = 0;
int main(int argc, char *argv[], char * const *envp) {
(void)envp;
......@@ -139,11 +269,31 @@ int main(int argc, char *argv[], char * const *envp) {
std::string code_name = "test.c";
std::string code = R"END(
#include <stdio.h>
static int global = 0;
void external (void);
void overloaded_inside (void);
void overloaded_inside (void)
{
printf("INSIDE INSIDE\n");
}
int demo (void)
{
printf("Hello, World!\n");
// printf("demo2: %d\n", demo2(20));
return 42;
global++;
printf("Hello, World (%d)!\n", global);
external();
overloaded_inside();
int i = 5;
printf("Entering loop\n");
while (i) {
printf("Looping\n");
i--;
}
printf("Exiting loop\n");
return 42;
}
)END";
......@@ -171,6 +321,7 @@ int demo (void)
args.push_back("/include");
args.push_back("-internal-externc-isystem");
args.push_back("/usr/include");
args.push_back("-O0");
llvm::ArrayRef<const char*> args_array(args);
clang::CompilerInvocation::CreateFromArgs(*CI, args_array, DiagnosticsEngine);
......@@ -202,99 +353,148 @@ int demo (void)
llvm::LLVMContext Context;
llvm::SMDiagnostic Err;
std::unique_ptr<llvm::Module> Owner = compilerAction->takeModule();
llvm::Module *Mod = Owner.get();
if (!Mod) {
Err.print(code_name.c_str(), llvm::errs());
exit(1);
}
std::unique_ptr<llvm::Module> Owner2 = llvm::CloneModule(*Owner);
/*
{
llvm::ExitOnError eoe(std::string(code_name) +
": bitcode didn't read correctly: ");
eoe(Mod->materializeAll());
}
llvm::SMDiagnostic Err;
if (!Mod) {
Err.print(code_name.c_str(), llvm::errs());
exit(1);
}
{
llvm::ExitOnError eoe(std::string(code_name) +
": bitcode didn't read correctly: ");
eoe(Mod->materializeAll());
}
std::unique_ptr<llvm::AssemblyAnnotationWriter> Annotator;
std::string dis_str;
llvm::raw_string_ostream dis_stream(dis_str);
Mod->print(dis_stream, Annotator.get());
std::cout << std::endl << std::endl << "\033[1;34m" << dis_str << std::endl << "\033[0m" << std::endl;
std::unique_ptr<llvm::AssemblyAnnotationWriter> Annotator;
std::string dis_str;
llvm::raw_string_ostream dis_stream(dis_str);
Mod->print(dis_stream, Annotator.get());
std::cout << std::endl << std::endl << "\033[1;34m" << dis_str << std::endl << "\033[0m" << std::endl;
}
*/
/*
{
std::string ErrorMsg;
llvm::Module *Mod = Owner.get();
llvm::EngineBuilder builder(std::move(Owner));
std::string ErrorMsg;
builder.setErrorStr(&ErrorMsg);
llvm::EngineBuilder builder(std::move(Owner));
builder.setMArch(llvm::codegen::getMArch());
builder.setMCPU(llvm::codegen::getCPUStr());
builder.setMAttrs(llvm::codegen::getFeatureList());
builder.setErrorStr(&ErrorMsg);
// if (auto RM = llvm::codegen::getExplicitRelocModel()) {
// builder.setRelocationModel(RM.getValue());
// }
builder.setMArch(llvm::codegen::getMArch());
builder.setMCPU(llvm::codegen::getCPUStr());
builder.setMAttrs(llvm::codegen::getFeatureList());
// if (auto CM = llvm::codegen::getExplicitCodeModel()) {
// builder.setCodeModel(CM.getValue());
// }
// if (auto RM = llvm::codegen::getExplicitRelocModel()) {
// builder.setRelocationModel(RM.getValue());
// }
builder.setEngineKind(llvm::EngineKind::Interpreter);
// if (auto CM = llvm::codegen::getExplicitCodeModel()) {
// builder.setCodeModel(CM.getValue());
// }
builder.setOptLevel(llvm::CodeGenOpt::None);
builder.setEngineKind(llvm::EngineKind::Interpreter);
llvm::TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags(llvm::Triple());
// if (llvm::codegen::getFloatABIForCalls() != llvm::FloatABI::Default) {
// Options.FloatABIType = llvm::codegen::getFloatABIForCalls();
// }
builder.setOptLevel(llvm::CodeGenOpt::None);
builder.setTargetOptions(Options);
llvm::TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags(llvm::Triple());
// if (llvm::codegen::getFloatABIForCalls() != llvm::FloatABI::Default) {
// Options.FloatABIType = llvm::codegen::getFloatABIForCalls();
// }
builder.setTargetOptions(Options);
std::unique_ptr<llvm::ExecutionEngine> EE(builder.create());
if (!EE) {
if (!ErrorMsg.empty())
llvm::WithColor::error(llvm::errs(), code_name)
<< "error creating EE: " << ErrorMsg << "\n";
else
llvm::WithColor::error(llvm::errs(), code_name) << "unknown error creating EE!\n";
exit(1);
}
EE->DisableLazyCompilation(false);
std::unique_ptr<llvm::ExecutionEngine> EE(builder.create());
if (!EE) {
if (!ErrorMsg.empty())
llvm::WithColor::error(llvm::errs(), code_name)
<< "error creating EE: " << ErrorMsg << "\n";
else
llvm::WithColor::error(llvm::errs(), code_name) << "unknown error creating EE!\n";
exit(1);
}
llvm::Function *EntryFn = Mod->getFunction("demo");
if (!EntryFn) {
llvm::WithColor::error(llvm::errs(), code_name.c_str())
<< '\'' << "demo" << "\' function not found in module.\n";
return -1;
}
EE->DisableLazyCompilation(false);
errno = 0;
llvm::Function *EntryFn = Mod->getFunction("demo");
if (!EntryFn) {
llvm::WithColor::error(llvm::errs(), code_name.c_str())
<< '\'' << "main" << "\' function not found in module.\n";
return -1;
}
errno = 0;
{ // Execute
// Run static constructors.
EE->runStaticConstructorsDestructors(false);
{ // Execute
// Run static constructors.
EE->runStaticConstructorsDestructors(false);
// Run main.
llvm::GenericValue Result = EE->runFunction(EntryFn, llvm::ArrayRef<llvm::GenericValue>());
uint64_t ResultValue = Result.IntVal.getZExtValue();
// Run main.
llvm::GenericValue Result = EE->runFunction(EntryFn, llvm::ArrayRef<llvm::GenericValue>());
uint64_t ResultValue = Result.IntVal.getZExtValue();
// Run static destructors.
EE->runStaticConstructorsDestructors(true);
// Run static destructors.
EE->runStaticConstructorsDestructors(true);
std::cout << "Returns: " << ResultValue << std::endl;
}
}
*/
{
Context = std::make_unique<llvm::LLVMContext>();
jit = ExitOnErr(GazelleJIT::Create());
{ // Pass
TheFPM = std::make_unique<llvm::legacy::FunctionPassManager>(Owner2.get());
TheFPM->add(new FuncModifier());
TheFPM->doInitialization();
for (llvm::Function &func : *Owner2) {
TheFPM->run(func);
}
TheFPM->doFinalization();
}
{
llvm::SMDiagnostic Err;
{
llvm::ExitOnError eoe(std::string(code_name) +
": bitcode didn't read correctly: ");
eoe(Owner2->materializeAll());
}
std::unique_ptr<llvm::AssemblyAnnotationWriter> Annotator;
std::string dis_str;
llvm::raw_string_ostream dis_stream(dis_str);
Owner2->print(dis_stream, Annotator.get());
std::cout << std::endl << std::endl << "\033[1;34m" << dis_str << std::endl << "\033[0m" << std::endl;
}
Owner2->setDataLayout(jit->getDataLayout());
auto RT = jit->getMainJITDylib().createResourceTracker();
auto Mod2TSM = llvm::orc::ThreadSafeModule(std::move(Owner2), std::move(Context));
auto H = jit->addModule(std::move(Mod2TSM), RT);
auto ExprSymbol = jit->lookup("demo");
assert(ExprSymbol && "Function not found");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
auto demoFunction = (int (*)(void))(intptr_t)ExprSymbol->getAddress();
#pragma clang diagnostic pop
auto ResultValue = demoFunction();
std::cout << "Returns: " << ResultValue << std::endl;
ExitOnErr(RT->remove());
}
return static_cast<int>(ResultValue);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment