-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First draft of supporting \result in Pallas specifications
- Loading branch information
1 parent
ce2783c
commit ffffac8
Showing
17 changed files
with
470 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package vct.col.ast.lang.llvm | ||
|
||
import vct.col.ast.node.NodeFamilyImpl | ||
import vct.col.ast.ops.LLVMResultOps | ||
import vct.col.ast.{LLVMResult, Type} | ||
import vct.col.print.Precedence | ||
|
||
trait LLVMResultImpl[G] extends NodeFamilyImpl[G] with LLVMResultOps[G] { | ||
this: LLVMResult[G] => | ||
override def t: Type[G] = func.decl.returnType | ||
|
||
override def precedence: Int = Precedence.ATOMIC | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#ifndef PALLAS_EXPRWRAPPERMAPPER_H | ||
#define PALLAS_EXPRWRAPPERMAPPER_H | ||
|
||
#include "vct/col/ast/col.pb.h" | ||
#include <llvm/IR/Function.h> | ||
#include <llvm/IR/PassManager.h> | ||
#include <optional> | ||
|
||
/** | ||
* Analysis-pass that maps functions that represent expression wrappers in a | ||
* Pallas specification to the function to whose specification they belong. | ||
*/ | ||
namespace pallas { | ||
|
||
enum PallasWrapperContext { | ||
FuncContractPre, | ||
FuncContractPost | ||
}; | ||
|
||
class EWMResult { | ||
private: | ||
llvm::Function *parentFunc; | ||
std::optional<PallasWrapperContext> context; | ||
|
||
public: | ||
explicit EWMResult(llvm::Function *parentFunc, | ||
std::optional<PallasWrapperContext> ctx); | ||
|
||
llvm::Function *getParentFunc(); | ||
|
||
std::optional<PallasWrapperContext> getContext(); | ||
}; | ||
|
||
class ExprWrapperMapper : public llvm::AnalysisInfoMixin<ExprWrapperMapper> { | ||
friend llvm::AnalysisInfoMixin<ExprWrapperMapper>; | ||
static llvm::AnalysisKey Key; | ||
|
||
public: | ||
using Result = EWMResult; | ||
|
||
/** | ||
* Maps functions that represent a Pallas expression wrapper to the function | ||
* to whose specification they belong to. | ||
* If a function does not belong to the contract of any function, | ||
* the result contains a nullpointer. | ||
*/ | ||
Result run(llvm::Function &F, llvm::FunctionAnalysisManager &FAM); | ||
}; | ||
|
||
} // namespace pallas | ||
#endif // PALLAS_EXPRWRAPPERMAPPER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef PALLAS_MD_H | ||
#define PALLAS_MD_H | ||
|
||
#include <llvm/IR/Function.h> | ||
#include <optional> | ||
#include <string> | ||
|
||
/** | ||
* Utils for working with the metadata-node of pallas specifications. | ||
*/ | ||
namespace pallas::utils { | ||
|
||
/** | ||
* Checks if the given function is labeled as a function from the pallas | ||
* specification-library. | ||
* If so, it returns an optinal that contains the string-identifier of the kind | ||
* of spec-livb function. | ||
* If it is not a function from the specification library, an empty optional is | ||
* returned. | ||
* @param f The function to check | ||
*/ | ||
std::optional<std::string> isPallasSpecLib(const llvm::Function &f); | ||
|
||
/** | ||
* Checks if the given function has a metadata-node that is labeled as a | ||
* Pallas function contract. | ||
*/ | ||
bool hasPallasContract(const llvm::Function &f); | ||
|
||
/** | ||
* Checks if the given function has a metadata-node that is labeled as a | ||
* VCLLVM contract. | ||
*/ | ||
bool hasVcllvmContract(const llvm::Function &f); | ||
|
||
/** | ||
* Checks if the given llvm function is marked as an expression wrapper of a | ||
* pallas specification. | ||
*/ | ||
bool isPallasExprWrapper(const llvm::Function &f); | ||
|
||
} // namespace pallas::utils | ||
|
||
#endif // PALLAS_MD_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#include "Passes/Function/ExprWrapperMapper.h" | ||
#include "Passes/Function/FunctionDeclarer.h" | ||
|
||
#include "Origin/OriginProvider.h" | ||
#include "Util/Constants.h" | ||
#include "Util/Exceptions.h" | ||
#include "Util/PallasMD.h" | ||
|
||
#include <llvm/IR/Metadata.h> | ||
|
||
namespace pallas { | ||
const std::string SOURCE_LOC = "Passes::Function::ExprWrapperMapper"; | ||
|
||
using namespace llvm; | ||
namespace col = vct::col::ast; | ||
|
||
/* | ||
* EWMResult | ||
*/ | ||
|
||
EWMResult::EWMResult(llvm::Function *parentFunc, | ||
std::optional<PallasWrapperContext> ctx) | ||
: parentFunc(parentFunc), context(ctx) {} | ||
|
||
llvm::Function *EWMResult::getParentFunc() { return parentFunc; } | ||
|
||
std::optional<PallasWrapperContext> EWMResult::getContext() { return context; } | ||
|
||
/* | ||
* ExpressionWrapperMapper | ||
*/ | ||
|
||
AnalysisKey ExprWrapperMapper::Key; | ||
|
||
ExprWrapperMapper::Result ExprWrapperMapper::run(Function &F, | ||
FunctionAnalysisManager &FAM) { | ||
|
||
auto *llvmModule = F.getParent(); | ||
|
||
// Check all functions in the current module | ||
for (Function &parentF : llvmModule->functions()) { | ||
// Check if the function has a pallas-contract | ||
if (!utils::hasPallasContract(parentF)) { | ||
continue; | ||
} | ||
auto *contract = parentF.getMetadata(constants::PALLAS_FUNC_CONTRACT); | ||
|
||
// Look at all of the clauses and check if they reference the | ||
// wrapper-function | ||
auto numOps = contract->getNumOperands(); | ||
unsigned int clauseIdx = 2; | ||
for (clauseIdx = 2; clauseIdx < numOps; ++clauseIdx) { | ||
// Try to get the third operand as a function | ||
auto *clause = | ||
dyn_cast<MDNode>(contract->getOperand(clauseIdx).get()); | ||
if (clause == nullptr || clause->getNumOperands() < 3) | ||
continue; | ||
auto *clauseWrapperMD = | ||
dyn_cast<ValueAsMetadata>(clause->getOperand(2).get()); | ||
if (clauseWrapperMD == nullptr) | ||
continue; | ||
auto *clauseWrapper = | ||
dyn_cast_if_present<Function>(clauseWrapperMD->getValue()); | ||
if (clauseWrapper == nullptr) | ||
continue; | ||
// Check if the wrapper-function in the clause is the function that | ||
// we are looking for. | ||
if (clauseWrapper == &F) { | ||
// Determine the context in which the wrapper is used. | ||
std::optional<PallasWrapperContext> ctx = std::nullopt; | ||
if (auto *fClauseTMD = | ||
dyn_cast<MDString>(clause->getOperand(0).get())) { | ||
auto clauseTStr = fClauseTMD->getString().str(); | ||
if (clauseTStr == pallas::constants::PALLAS_REQUIRES) { | ||
ctx = PallasWrapperContext::FuncContractPre; | ||
} else if (clauseTStr == | ||
pallas::constants::PALLAS_ENSURES) { | ||
ctx = PallasWrapperContext::FuncContractPost; | ||
} | ||
} | ||
return EWMResult(&parentF, ctx); | ||
} | ||
} | ||
} | ||
return EWMResult(nullptr, std::nullopt); | ||
} | ||
|
||
} // namespace pallas |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.