Commit a432bc51 authored by Henrich Lauko's avatar Henrich Lauko

lart: Add metadata to calls that return abstract value.

parent 64419102
......@@ -3,6 +3,7 @@
#include <lart/abstract/annotation.h>
#include <lart/support/util.h>
#include <lart/abstract/util.h>
#include <lart/abstract/meta.h>
namespace lart::abstract {
......@@ -29,6 +30,16 @@ namespace lart::abstract {
{
annotation_to_domain_metadata< llvm::Function >( meta::tag::abstract, m );
annotation_to_transform_metadata< llvm::Function >( meta::tag::transform::prefix, m );
for ( auto & fn : m ) {
if ( auto meta = meta::get( &fn, meta::tag::abstract ) ) {
for ( auto user : fn.users() ) {
if ( auto val = lower_constant_expr_call( user ) )
if ( auto call = llvm::dyn_cast< llvm::CallInst >( val ) )
meta::set( call, meta::tag::abstract, meta.value() );
}
}
}
}
} // namespace lart::abstract
......@@ -234,27 +234,6 @@ using lart::util::get_module;
}
}
llvm::Value * lower_constant_expr_call( llvm::ConstantExpr * ce ) {
if ( ce->getNumUses() > 0 ) {
if ( auto orig = llvm::dyn_cast< llvm::CallInst >( *ce->user_begin() ) ) {
auto fn = ce->getOperand( 0 );
llvm::IRBuilder<> irb( orig );
auto call = irb.CreateCall( fn );
if ( call->getType() != orig->getType() ) {
auto cast = irb.CreateBitCast( call, orig->getType() );
orig->replaceAllUsesWith( cast );
} else {
orig->replaceAllUsesWith( call );
}
orig->eraseFromParent();
return call;
}
}
return nullptr;
}
std::vector< DomainMetadata > domains( llvm::Module & m ) {
std::vector< DomainMetadata > doms;
specification_function_walker( m, [&] ( const auto& fn, const auto& ) {
......
......@@ -5,6 +5,7 @@ DIVINE_RELAX_WARNINGS
#include <llvm/IR/Type.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Instructions.h>
DIVINE_UNRELAX_WARNINGS
......@@ -20,6 +21,26 @@ namespace lart::abstract
auto get_potentially_called_functions( llvm::CallInst* call ) -> std::vector< llvm::Function * >;
auto get_some_called_function( llvm::CallInst * call ) -> llvm::Function *;
static inline llvm::Value * lower_constant_expr_call( llvm::Value * val ) {
auto ce = llvm::dyn_cast< llvm::ConstantExpr >( val );
if ( !ce )
return val;
if ( ce->getNumUses() == 0 )
return nullptr;
if ( auto orig = llvm::dyn_cast< llvm::CallInst >( *ce->user_begin() ) ) {
auto fn = ce->getOperand( 0 );
llvm::IRBuilder<> irb( orig );
llvm::Value * call = irb.CreateCall( fn );
if ( call->getType() != orig->getType() )
call = irb.CreateBitCast( call, orig->getType() );
orig->replaceAllUsesWith( call );
orig->eraseFromParent();
return call;
}
return nullptr;
}
template< const char * tag >
auto calls_with_tag( llvm::Module & m )
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment