loggerpass.cpp
No OneTemporary

File Metadata

Created
Fri, Mar 13, 7:41 PM

loggerpass.cpp

/*
* logging.cpp
*
* Created on: Jun 23, 2015
* Author: pgess
*/
#include <pass/loggerpass.h>
#include "compilation/instr-containers.h"
#include "utils.h"
using namespace std;
using namespace llvm;
namespace xreate {
void LoggerPass::init(ClaspLayer* clasp){
auto model = clasp->query(Config::get("logging.id"));
if(!model) return;
for (ClaspLayer::ModelIterator rec = model->first; rec!=model->second; ++rec){
std::tuple<SymbolPacked> _v =ClaspLayer::parse<SymbolPacked>(rec->second);
Symbol v = clasp->unpack(get<0>(_v));
SymbolAttachments::put<IsLogging>(v, true);
}
}
void
LoggerPass::process(const Expression& expression, PassContext context, const std::string& varDecl){
if (varDecl.size()){
Symbol v = context.scope->findSymbol(varDecl);
if (SymbolAttachments::get<IsLogging>(v, false)){
CompilePass::FunctionUnit* func = compiler->getFunctionUnit(context.function);
CompilePass::CodeScopeUnit* scope = func->getScopeUnit(context.scope);
CompilePass::Context compilationContext{func, scope, compiler};
inject(v, compilationContext);
}
}
return AbstractPass<void>::process(expression, context, varDecl);
}
void LoggerPass::inject(const Symbol& symbol, const CompilePass::Context& context){
llvm::Value* source = context.scope->compileSymbol(symbol);
ExpandedType typSource = man->root->expandType(CodeScope::findDefinition(symbol));
string format = "";
switch (typSource->__value) {
case TypePrimitive::Int : case TypePrimitive::Num : case TypePrimitive::I32: case TypePrimitive::I8:
format = "%d\n";
break;
case TypePrimitive::String:
format = "%s\n";
break;
default:
assert(false && "No appropriate type for logging");
}
containers::Instructions compiler(context);
LLVMLayer* llvm = context.pass->man->llvm;
llvm->builder.SetInsertPoint(*source->use_begin());
llvm::Value* formatRaw = compiler.compileConstantStringAsPChar(format, "logformat");
llvm->builder.CreateCall2(refPrintf, formatRaw, source);
}
void
LoggerPass::initOutput(){
LLVMLayer* llvm = man->llvm;
refPrintf = llvm->module->getFunction("printf");
if (!refPrintf) {
PointerType* typPtrI8 = PointerType::get(IntegerType::get(llvm->module->getContext(), 8), 0);
std::vector<Type*>argsPrintf{typPtrI8};
FunctionType* signaturePrintf = FunctionType::get(
/*Result=*/IntegerType::get(llvm->module->getContext(), 32),
/*Params=*/argsPrintf,
/*isVarArg=*/true);
refPrintf = llvm::Function::Create(
/*Type=*/signaturePrintf,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"printf", llvm->module); // (external, no body)
refPrintf->setCallingConv(CallingConv::C);
}
}
LoggerPass::LoggerPass(PassManager* manager)
: AbstractPass<void>(manager)
{
initOutput();
init(man->clasp);
}
void
LoggerPass::initDependencies(CompilePass* pass){
compiler = pass;
}
} /* namespace xreate */

Event Timeline