Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F3997536
transformations.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Jul 8, 9:48 PM
Size
4 KB
Mime Type
text/x-c++
Expires
Fri, Jul 10, 9:48 PM (1 d, 11 h)
Engine
blob
Format
Raw Data
Handle
272620
Attached To
rXR Xreate
transformations.cpp
View Options
/*
* File: Transformations.cpp
* Author: pgess
*
* Created on June 18, 2016, 6:23 PM
*/
#include "compilation/transformations.h"
#include "pass/compilepass.h"
#include "llvmlayer.h"
#include <llvm/IR/Value.h>
using namespace llvm;
namespace xreate { namespace compilation {
Transformations::Transformations(CompilePass* passCompilation): pass(passCompilation) {
}
void
Transformations::subscribe(const std::string& annotation, int handler){
__subscriptions.emplace(annotation, handler);
}
bool
Transformations::isAcceptable(const Expression& expression){
//check subscription based on expression attachments
if (Attachments::get<Expression, Transformations>(expression, {false, 0}).flagSubscribed){
return true;
}
//subscription based on expression annotations;
if (expression.tags.size() == 0) return false;
for (auto tag: expression.tags) {
if (__subscriptions.count(tag.first)){
return true;
}
}
return false;
}
Expression
Transformations::transform(const Expression& expression, const Context& ctx){
Expression result = expression;
for (auto handler: getAppropriateTransformers(expression)){
result = handler->transform(result, ctx);
}
return result;
}
llvm::Value*
Transformations::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
for (auto handler: getAppropriateTransformers(expression)){
raw = handler->transform(expression, raw, ctx);
}
return raw;
}
std::list<Transformer*>
Transformations::getAppropriateTransformers(const Expression& expression){
std::list<Transformer*> result;
for (auto tag: expression.tags) {
if (__subscriptions.count(tag.first)){
auto handlers = __subscriptions.equal_range(tag.first);
for (auto handlerIt=handlers.first; handlerIt!= handlers.second; ++handlerIt){
Transformer* handler = __transformers[handlerIt->second];
if (handler->isAcceptable(expression)){
result.push_back(handler);
}
}
}
}
auto subscriberInternal = Attachments::get<Expression, Transformations>(expression, {false, 0});
if (subscriberInternal.flagSubscribed){
result.push_back(__transformers[subscriberInternal.subscriberId]);
}
return result;
}
TransformerSaturation::TransformerSaturation(Transformations* man)
: __man(man) {
man->subscribe("break", TransformerInfo<TransformerSaturation>::id);
}
bool
TransformerSaturation::isAcceptable(const Expression& expression){
return true;
}
bool
TransformerSaturation::exists() const{
return __block != nullptr;
}
llvm::Value*
TransformerSaturation::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
__block = __man->pass->man->llvm->builder.GetInsertBlock();
return raw;
}
llvm::BasicBlock*
TransformerSaturation::getBlock() const{
return __block;
}
void
TransformerSaturation::inject(llvm::BasicBlock* blockAllocation, llvm::BasicBlock* blockExit, compilation::Context context){
llvm::Type* tyInt1 = llvm::Type::getInt1Ty(llvm::getGlobalContext());
llvm::Value* valueConstOne = llvm::ConstantInt::get(tyInt1, 1);
llvm::Value* valueConstFalse = llvm::ConstantInt::get(tyInt1, 0);
//allocation of saturation flag
IRBuilder<> builderAlloca(blockAllocation, blockAllocation->getFirstInsertionPt());
llvm::Value* flagSaturation = builderAlloca.CreateAlloca(tyInt1, valueConstOne, "flagSaturation");
builderAlloca.CreateStore(valueConstFalse, flagSaturation, true);
//set up saturation flag
llvm::BasicBlock* blockSaturation = __block;
IRBuilder<> builderSaturation(blockSaturation, blockSaturation->getFirstInsertionPt());
builderSaturation.CreateStore(valueConstOne, flagSaturation, true);
//check saturation flag:
//TODO remove blockContinue, receive from caller block to continue.
llvm::BasicBlock *blockContinue = llvm::BasicBlock::Create(llvm::getGlobalContext(), "continue", context.function->raw);
context.pass->man->llvm->builder.CreateCondBr(context.pass->man->llvm->builder.CreateLoad(flagSaturation), blockExit, blockContinue);
context.pass->man->llvm->builder.SetInsertPoint(blockContinue);
}
}}
Event Timeline
Log In to Comment