Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2729498
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
Fri, Mar 13, 2:46 AM
Size
4 KB
Mime Type
text/x-c++
Expires
Sun, Mar 15, 2:46 AM (1 d, 43 m)
Engine
blob
Format
Raw Data
Handle
243040
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