versions.h
No OneTemporary

File Metadata

Created
Fri, Mar 13, 7:50 PM

versions.h

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* versions.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on January 21, 2017, 1:24 PM
*/
/**
* \file
* \brief CodeScope's Decorator to support Versions
*/
#include "pass/versionspass.h"
#include "pass/compilepass.h"
#include "llvmlayer.h"
namespace xreate {
class CompilePass;
namespace compilation {
class ICodeScopeUnit;
class IFunctionUnit;
}
namespace versions{
/**\brief Enables compilation of code with versioned variables
* \details Dictates order of computation determined by VersionsPass
* \extends xreate::compilation::ICodeScopeUnit
* \sa VersionsPass, VersionsGraph
*/
template<class Parent>
class VersionsScopeDecorator: public Parent{
typedef VersionsScopeDecorator<Parent> SELF;
public:
VersionsScopeDecorator(CodeScope* codeScope, compilation::IFunctionUnit* f, CompilePass* compilePass): Parent(codeScope, f, compilePass){}
virtual llvm::Value* processSymbol(const Symbol& s, std::string hintSymbol=""){
if (Attachments::exists<VersionImposedDependency>(s)){
const std::list<Symbol> dependencies = Attachments::get<VersionImposedDependency>(s);
for(const Symbol& symbolDependent: dependencies){
processSymbol(symbolDependent);
}
}
llvm::Value* result = Parent::processSymbol(s, hintSymbol);
if (s.identifier.version == VERSION_INIT){
llvm::Value* storage = SELF::processIntrinsicInit(result->getType(), hintSymbol);
setSymbolStorage(s, storage);
processIntrinsicCopy(result, storage);
return compilation::ICodeScopeUnit::pass->man->llvm->builder.CreateLoad(storage);
} else if (s.identifier.version != VERSION_NONE){
Symbol symbolInitVersion = getSymbolInitVersion(s);
llvm::Value* storage = getSymbolStorage(symbolInitVersion);
processIntrinsicCopy(result, storage);
return compilation::ICodeScopeUnit::pass->man->llvm->builder.CreateLoad(storage);
}
return result;
}
llvm::Value*
processIntrinsicInit(llvm::Type* typeStorage, const std::string& hintVarDecl=""){
llvm::IntegerType* tyInt = llvm::Type::getInt32Ty(llvm::getGlobalContext());
llvm::ConstantInt* constOne = llvm::ConstantInt::get(tyInt, 1, false);
return compilation::ICodeScopeUnit::pass->man->llvm->builder.CreateAlloca(typeStorage, constOne, hintVarDecl);
}
void
processIntrinsicCopy(llvm::Value* value, llvm::Value* storage){
compilation::ICodeScopeUnit::pass->man->llvm->builder.CreateStore(value, storage);
}
private:
std::map<Symbol, llvm::Value*> __symbolStorage;
static Symbol
getSymbolInitVersion(const Symbol& s){
return Symbol{ScopedSymbol{s.identifier.id, VERSION_INIT}, s.scope};
}
llvm::Value*
getSymbolStorage(const Symbol& s){
return __symbolStorage.at(s);
}
void setSymbolStorage(const Symbol& s, llvm::Value* storage){
__symbolStorage[s] = storage;
}
};
} } //end of namespace xreate::versions
// llvm::Value*
// processIntrinsicInitAndCopy(){
//
// }
//llvm::Value*
//process(const Expression& expr, const std::string& hintVarDecl){
// case Operator::CALL_INTRINSIC: {
// enum INRINSIC{INIT, COPY};
//
// const ExpandedType& typSymbol = pass->man->root->expandType(expr.type);
//
// INTRINSIC op = (INTRINSIC) expr.getValueDouble();
//
// switch (op){
// case INIT: {
// llvm::Type* typSymbolRaw = l.toLLVMType(typSymbol);
//
//
// return storage;
// }
//
// case COPY: {
// llvm::Type* typSymbolRaw = l.toLLVMType(typSymbol);
// llvm::value* valueOriginal = process(expr.getOperands()[0], hintVarDecl);
// llvm::Value* storage = l.builder.CreateAlloca(typSymbolRaw, constOne, hintVarDecl);
// llvm::Value* valueCopy = l.builder.CreateStore(valueOriginal, storage);
//
// return valueCopy;
// }
// }
// return;
// }
//}
//};

Event Timeline