Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: |
|
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
bb17e9f3dd6fb2f5be52f7a0e20f2115 |
| User & Date: | achavasse 2020-05-25 22:08:44.976 |
Context
|
2020-05-30
| ||
| 14:25 | Enable's z3 new arith solver as the old one takes a very long time in one of the tests with the latest version of z3. check-in: 4b56796791 user: achavasse tags: trunk | |
|
2020-05-25
| ||
| 22:08 |
| |
|
2020-05-23
| ||
| 12:58 |
| |
Changes
Changes to bs/builtins/api/compiler.cpp.
| ︙ | ︙ | |||
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
{
auto ft = FromValue< FuncType >( f );
if( !ft )
return PoisonValue();
return ToValue( BuildExternalFunc( *ft, symbol ) );
} );
RegisterBuiltinFunc< void ( string, Value ) >( e, "CreateConstant"_sid,
[pEnv]( const string& name, const Value& v )
{
if( !v.isConstant() )
{
DiagnosticsManager::GetInstance().emitErrorMessage( v.locationId(),
| > > > > > > > > > > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
{
auto ft = FromValue< FuncType >( f );
if( !ft )
return PoisonValue();
return ToValue( BuildExternalFunc( *ft, symbol ) );
} );
RegisterBuiltinFunc< Eager< Value > ( Value, string ) >( e, "ExternalVarArgFunction"_sid,
[pEnv]( const Value& f, const string& symbol )
{
auto ft = FromValue< FuncType >( f );
if( !ft )
return PoisonValue();
return ToValue( BuildExternalFunc( *ft, symbol, true ) );
} );
RegisterBuiltinFunc< void ( string, Value ) >( e, "CreateConstant"_sid,
[pEnv]( const string& name, const Value& v )
{
if( !v.isConstant() )
{
DiagnosticsManager::GetInstance().emitErrorMessage( v.locationId(),
|
| ︙ | ︙ |
Changes to bs/builtins/builtins.cpp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include "builtins/builtins.h"
namespace goose::builtins
{
void SetupBuiltins( Env& e )
{
e.extDropValue() = CreateOverloadSet( e, "DropValue"_sid );
e.extDestroyValue() = CreateOverloadSet( e, "DestroyValue"_sid );
e.extLowerTypeForRuntime() = CreateOverloadSet( e, "LowerTypeForRuntime"_sid );
e.extInitialize() = CreateOverloadSet( e, "Initialize"_sid );
SetupBuiltinTypes( e );
SetupBuiltinOperators( e );
SetupBuiltinStatements( e );
SetupBuiltinApi( e );
}
| > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include "builtins/builtins.h"
namespace goose::builtins
{
void SetupBuiltins( Env& e )
{
e.extDropValue() = CreateOverloadSet( e, "DropValue"_sid );
e.extDestroyValue() = CreateOverloadSet( e, "DestroyValue"_sid );
e.extLowerTypeForRuntime() = CreateOverloadSet( e, "LowerTypeForRuntime"_sid );
e.extLowerConstantForRuntime() = CreateOverloadSet( e, "LowerConstantForRuntime"_sid );
e.extInitialize() = CreateOverloadSet( e, "Initialize"_sid );
SetupBuiltinTypes( e );
SetupBuiltinOperators( e );
SetupBuiltinStatements( e );
SetupBuiltinApi( e );
}
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/bfunc.cpp.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 |
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "builtin"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
| > | > | > | > | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "builtin"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif info
SubTerm() // varArg
)
);
if( decomp )
return true;
decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "builtin_eager"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif info
SubTerm() // varArg
)
);
return !!decomp;
}
bool IsNonEagerBuiltinFunc( const Value& func )
{
auto funcType = ValueFromIRExpr( func.type() );
assert( funcType );
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "builtin"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif info
SubTerm() // varArg
)
);
return !!decomp;
}
bool IsEagerBuiltinFunc( const Value& func )
{
auto funcType = ValueFromIRExpr( func.type() );
assert( funcType );
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "builtin_eager"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif info
SubTerm() // varArg
)
);
return !!decomp;
}
const BuiltinFuncWrapper& GetBuiltinFuncWrapper( const Value& func )
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/bfunc.inl.
| ︙ | ︙ | |||
92 93 94 95 96 97 98 |
template< typename R, typename... T >
const Term& Bridge< R ( T... ) >::Type( const ptr< builtins::FuncVerificationInfos >& fvi )
{
static auto type = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
builtins::is_eager_v< R > ? TSID( builtin_eager ) : TSID( builtin ),
sema::Quote( sema::DomainAny() ), GetValueType< builtins::remove_eager_t< R > >(),
sema::Quote( BuildBuiltinFuncParamTypeList< T... >() ),
| | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
template< typename R, typename... T >
const Term& Bridge< R ( T... ) >::Type( const ptr< builtins::FuncVerificationInfos >& fvi )
{
static auto type = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
builtins::is_eager_v< R > ? TSID( builtin_eager ) : TSID( builtin ),
sema::Quote( sema::DomainAny() ), GetValueType< builtins::remove_eager_t< R > >(),
sema::Quote( BuildBuiltinFuncParamTypeList< T... >() ),
static_pointer_cast< void >( fvi ), TERM( 0U )
) ) );
return type;
}
template< typename R, typename... T >
template< typename F >
Value Bridge< R ( T... ) >::ToValue( F&& func, const ptr< builtins::FuncVerificationInfos >& fvi )
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/build.cpp.
| ︙ | ︙ | |||
48 49 50 51 52 53 54 |
ValueToIRExpr( BuildComputedValue( rtTerm, llr::Placeholder( rtTerm, name ) ) ) );
}
auto pVerifInfos = make_shared< FuncVerificationInfos >( move( verificationIdentity ) );
return FuncType( domain, ValueToIRExpr( returnType ), tv, move( pVerifInfos ) );
}
| | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
ValueToIRExpr( BuildComputedValue( rtTerm, llr::Placeholder( rtTerm, name ) ) ) );
}
auto pVerifInfos = make_shared< FuncVerificationInfos >( move( verificationIdentity ) );
return FuncType( domain, ValueToIRExpr( returnType ), tv, move( pVerifInfos ) );
}
Func BuildExternalFunc( FuncType funcType, const string& symbol, bool varArg )
{
funcType.setDomain( DomainRunTime() );
funcType.setVarArg( varArg );
return Func( funcType, symbol );
}
Func BuildFunc( const Context& c, const Term& funcIdentity, const Term& domain, const Value& returnType, const Value& paramsDecl, const ptr< void >& unparsedBody, Context& out_bodyContext )
{
auto funcType = BuildFuncType( c, domain, returnType, paramsDecl );
return BuildFunc( c, funcType, funcIdentity, paramsDecl, unparsedBody, out_bodyContext );
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/build.h.
1 2 3 4 5 6 7 |
#ifndef GOOSE_BUILTINS_FUNC_BUILD_H
#define GOOSE_BUILTINS_FUNC_BUILD_H
namespace goose::builtins
{
extern FuncType BuildFuncType( const Context& c, const Term& domain, const Value& returnType, const Value& params );
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#ifndef GOOSE_BUILTINS_FUNC_BUILD_H
#define GOOSE_BUILTINS_FUNC_BUILD_H
namespace goose::builtins
{
extern FuncType BuildFuncType( const Context& c, const Term& domain, const Value& returnType, const Value& params );
extern Func BuildExternalFunc( FuncType funcType, const string& symbol, bool varArg = false );
extern Func BuildFunc( const Context& c, const Term& funcIdentity, const Term& domain, const Value& returnType, const Value& paramsDecl, const ptr< void >& unparsedBody, Context& out_bodyContext );
extern Func BuildFunc( const Context& c, const FuncType& funcType, const Term& funcIdentity, const Value& paramsDecl, const ptr< void >& unparsedBody,
Context& out_bodyContext );
extern Term BuildCallPatternFromFuncType( const Value& funcType );
}
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/func.cpp.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 |
namespace goose::builtins
{
const Term& FuncPattern::GetPattern()
{
static auto pattern = ValueToIRExpr(
Value( TypeType(), VEC( TSID( func ), HOLE( "llvmType"_sid ),
HOLE( "_"_sid ), HOLE( "_"_sid ), HOLE( "_"_sid ),
| | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
namespace goose::builtins
{
const Term& FuncPattern::GetPattern()
{
static auto pattern = ValueToIRExpr(
Value( TypeType(), VEC( TSID( func ), HOLE( "llvmType"_sid ),
HOLE( "_"_sid ), HOLE( "_"_sid ), HOLE( "_"_sid ),
HOLE( "_"_sid ), HOLE( "_"_sid ) ) ) );
return pattern;
}
bool IsExternalFunc( const Value& f )
{
if( !f.isConstant() )
|
| ︙ | ︙ | |||
37 38 39 40 41 42 43 |
auto result = Decompose( t.val(),
Vec(
Lit( "func"_sid ),
Val< void* >(),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
| > | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
auto result = Decompose( t.val(),
Vec(
Lit( "func"_sid ),
Val< void* >(),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif infos
SubTerm() // VarArg
)
);
return !!result;
}
Term GetFuncSig( const Value& func )
|
| ︙ | ︙ | |||
60 61 62 63 64 65 66 |
auto typeDecomp = Decompose( funcType.val(),
Vec(
Lit( "func"_sid ),
SubTerm(), // kind
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
| > | | > | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
auto typeDecomp = Decompose( funcType.val(),
Vec(
Lit( "func"_sid ),
SubTerm(), // kind
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif infos
SubTerm() // VarArg
)
);
assert( typeDecomp );
auto&& [kind, domain, rtype, ptypes, vinf, varArg] = *typeDecomp;
return VEC( *Unquote( domain ), *Unquote( ptypes ), rtype );
}
Term GetFuncRType( const Value& func )
{
auto funcType = ValueFromIRExpr( func.type() );
assert( funcType );
auto typeDecomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
SubTerm(), // kind
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif infos
SubTerm() // VarArg
)
);
assert( typeDecomp );
auto&& [kind, domain, rtype, ptypes, vinf, varArg] = *typeDecomp;
return rtype;
}
const llr::Func* GetFuncLLR( const Value& f )
{
if( !f.isConstant() )
|
| ︙ | ︙ | |||
152 153 154 155 156 157 158 |
return TypeType();
}
Value Bridge< FuncType >::ToValue( const FuncType& ft )
{
return Value( Type(), VEC( TSID( func ), TERM( ft.llvmType() ),
Quote( ft.domain() ), ft.returnType(), Quote( ft.params() ),
| | > | > | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
return TypeType();
}
Value Bridge< FuncType >::ToValue( const FuncType& ft )
{
return Value( Type(), VEC( TSID( func ), TERM( ft.llvmType() ),
Quote( ft.domain() ), ft.returnType(), Quote( ft.params() ),
static_pointer_cast< void >( ft.verifInfos() ),
TERM( ft.varArg() ? 1U : 0U ) ) );
}
optional< FuncType > Bridge< FuncType >::FromValue( const Value& v )
{
auto result = Decompose( v.val(),
Vec(
Lit( "func"_sid ),
Val< void* >(),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
Val< ptr< void > >(), // verif infos
Val< uint32_t >() // varArg
)
);
if( !result )
return nullopt;
auto&& [llvmtype, domain, rtype, params, vinf, varArg] = *result;
return FuncType( *Unquote( domain ), rtype, *Unquote( params ),
static_pointer_cast< FuncVerificationInfos >( vinf ),
static_cast< llvm::FunctionType* >( llvmtype ), varArg );
}
Term Bridge< Func >::Type( const builtins::Func& func )
{
return ValueToIRExpr( ::ToValue( func.type() ) );
}
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/func.h.
| ︙ | ︙ | |||
83 84 85 86 87 88 89 |
Term m_postConditions = VEC();
};
class FuncType
{
public:
template< typename D, typename R, typename P, typename VI >
| | | > > > > > > > > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
Term m_postConditions = VEC();
};
class FuncType
{
public:
template< typename D, typename R, typename P, typename VI >
FuncType( D&& domain, R&& returnType, P&& params, VI&& verifInfos, llvm::FunctionType* pLLVMType = nullptr, bool varArg = false ) :
m_domain( forward< D >( domain ) ),
m_returnType( forward< R >( returnType ) ),
m_params( forward< P >( params ) ),
m_verifInfos( forward< VI >( verifInfos ) ),
m_pllvmType( pLLVMType ),
m_varArg( varArg )
{}
const auto& domain() const { return m_domain; }
const auto& returnType() const { return m_returnType; }
const auto& params() const { return m_params; }
const auto& verifInfos() const { return m_verifInfos; }
auto* llvmType() const { return m_pllvmType; }
bool varArg() const { return m_varArg; }
template< typename D >
void setDomain( D&& domain )
{
m_domain = forward< D >( domain );
}
void setVarArg( bool varArg )
{
m_varArg = varArg;
}
private:
Term m_domain;
Term m_returnType;
Term m_params;
ptr< FuncVerificationInfos > m_verifInfos;
llvm::FunctionType* m_pllvmType = nullptr;
bool m_varArg = false;
};
extern bool IsExternalFunc( const Value& f );
extern bool IsFuncType( const Value& t );
class Func
{
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/invoke.cpp.
| ︙ | ︙ | |||
111 112 113 114 115 116 117 |
void SetupFunctionInvocationRule( Env& e )
{
e.invocationRuleSet()->addRule(
ValueToIRExpr( ValuePattern( ANYTERM( _ ),
ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ),
| | | 111 112 113 114 115 116 117 118 119 120 121 122 123 |
void SetupFunctionInvocationRule( Env& e )
{
e.invocationRuleSet()->addRule(
ValueToIRExpr( ValuePattern( ANYTERM( _ ),
ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ),
ANYTERM( _ ), ANYTERM( _ ) ) ) ),
ANYTERM( _ ) ) ),
GetFuncInvocationRule() );
}
}
|
Changes to bs/builtins/types/func/lower.cpp.
| ︙ | ︙ | |||
58 59 60 61 62 63 64 |
return true;
} );
if( !success )
return nullopt;
| | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
return true;
} );
if( !success )
return nullopt;
auto* pLLVMType = llvm::FunctionType::get( GetLLVMType( *rt ), paramTypes, ft.varArg() );
if( !pLLVMType )
return nullopt;
return FuncType( ft.domain(), ValueToIRExpr( *rt ), pv, nullptr, pLLVMType );
}
void SetupFunctionLowering( Env& e )
|
| ︙ | ︙ |
Changes to bs/builtins/types/func/unify.cpp.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 |
{
auto lhsVal = *ValuePatternFromIRExpr( lhs );
lhsVal.sort() = HOLE( "_"_sid );
co_yield Unify( ValueToIRExpr( lhsVal ), rhs, uc );
} );
auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
| | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
{
auto lhsVal = *ValuePatternFromIRExpr( lhs );
lhsVal.sort() = HOLE( "_"_sid );
co_yield Unify( ValueToIRExpr( lhsVal ), rhs, uc );
} );
auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( RT ), ANYTERM( P ), ANYTERM( _ ), ANYTERM( VA ) ) ) );
auto tFuncTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( texpr ), TSID( tfunc ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );
// func type param / func arg
e.unificationRuleSet()->addSymRule( URINFOS,
|
| ︙ | ︙ |
Changes to bs/builtins/types/intrinsic/intrinsic.cpp.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 |
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "intrinsic"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
| > | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
Lit( "intrinsic"_sid ),
SubTerm(), // domain
SubTerm(), // return type
SubTerm(), // param types
SubTerm(), // verif info
SubTerm() // varArg
)
);
return !!decomp;
}
const BuiltinIntrinsicFuncWrapper& GetBuiltinIntrinsicFuncWrapper( const Value& func )
|
| ︙ | ︙ |
Changes to bs/builtins/types/intrinsic/intrinsic.inl.
1 2 3 4 5 6 7 8 9 10 11 12 |
#ifndef GOOSE_BUILTINS_TYPES_INTRINSIC_INL
#define GOOSE_BUILTINS_TYPES_INTRINSIC_INL
namespace goose::ir
{
template< bool useVerifDomain, typename R, typename... T >
const Term& IntrinsicBridge< useVerifDomain, R, T... >::Type( const ptr< builtins::FuncVerificationInfos >& fvi )
{
static auto dom = useVerifDomain ? sema::DomainVerification() : sema::DomainAny();
static auto type = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ), TSID( intrinsic ),
sema::Quote( dom ), GetValueType< Value >(),
sema::Quote( BuildBuiltinFuncParamTypeList< T... >() ),
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#ifndef GOOSE_BUILTINS_TYPES_INTRINSIC_INL
#define GOOSE_BUILTINS_TYPES_INTRINSIC_INL
namespace goose::ir
{
template< bool useVerifDomain, typename R, typename... T >
const Term& IntrinsicBridge< useVerifDomain, R, T... >::Type( const ptr< builtins::FuncVerificationInfos >& fvi )
{
static auto dom = useVerifDomain ? sema::DomainVerification() : sema::DomainAny();
static auto type = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ), TSID( intrinsic ),
sema::Quote( dom ), GetValueType< Value >(),
sema::Quote( BuildBuiltinFuncParamTypeList< T... >() ),
static_pointer_cast< void >( fvi ), TERM( 0U )
) ) );
return type;
}
template< bool useVerifDomain, typename R, typename... T >
template< typename F >
Value IntrinsicBridge< useVerifDomain, R, T... >::ToValue( F&& func, const ptr< builtins::FuncVerificationInfos >& fvi )
|
| ︙ | ︙ |
Changes to bs/builtins/types/overloadset/unify.cpp.
1 2 3 4 5 6 7 8 9 10 |
#include "builtins/builtins.h"
using namespace goose;
using namespace goose::ir;
namespace goose::builtins
{
void SetupOverloadSetUnification( Env& e )
{
auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "builtins/builtins.h"
using namespace goose;
using namespace goose::ir;
namespace goose::builtins
{
void SetupOverloadSetUnification( Env& e )
{
auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( VA ) ) ) );
auto tFuncTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( texpr ), TSID( tfunc ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );
// func type param / overloadset arg
e.unificationRuleSet()->addSymRule( URINFOS,
|
| ︙ | ︙ |
Changes to bs/builtins/types/runtime/record.cpp.
| ︙ | ︙ | |||
43 44 45 46 47 48 49 |
llvm::Type* GetLLVMType( const RecordType& rt )
{
vector< llvm::Type* > elements;
elements.reserve( rt.m_memberTypes->terms().size() );
for( auto&& mt : rt.m_memberTypes->terms() )
| > > > | > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
llvm::Type* GetLLVMType( const RecordType& rt )
{
vector< llvm::Type* > elements;
elements.reserve( rt.m_memberTypes->terms().size() );
for( auto&& mt : rt.m_memberTypes->terms() )
{
auto llvmType = GetLLVMType( *ValueFromIRExpr( mt ) );
assert( llvmType );
elements.emplace_back( llvmType );
}
return llvm::StructType::get( GetLLVMContext(), elements, rt.m_packed );
}
}
namespace goose::ir
{
|
| ︙ | ︙ |
Changes to bs/builtins/types/runtime/record.h.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
m_memberTypes( forward< M >( memberTypes ) ),
m_packed( packed )
{}
pvec m_memberTypes;
bool m_packed = false;
};
extern llvm::Type* GetLLVMType( const RecordType& rt );
}
namespace goose::ir
{
template<>
| > > > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
m_memberTypes( forward< M >( memberTypes ) ),
m_packed( packed )
{}
pvec m_memberTypes;
bool m_packed = false;
};
template< typename T, typename V >
Value CreateRecord( T&& types, V&& vals, bool packed )
{
auto rt = ValueToIRExpr( ToValue( RecordType( forward< T >( types ), packed ) ) );
return Value( move( rt ), forward< V >( vals ) );
}
extern llvm::Type* GetLLVMType( const RecordType& rt );
}
namespace goose::ir
{
template<>
|
| ︙ | ︙ |
Changes to bs/builtins/types/runtime/runtime.cpp.
1 2 3 4 5 6 7 8 9 10 11 |
#include "builtins/builtins.h"
#include "codegen/codegen.h"
using namespace goose;
using namespace goose::builtins;
using namespace goose::codegen;
namespace goose::builtins
{
bool IsRuntimeType( const Value& t )
{
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include "builtins/builtins.h"
#include "codegen/codegen.h"
using namespace goose;
using namespace goose::builtins;
using namespace goose::codegen;
namespace goose::builtins
{
bool IsRuntimeType( const Value& t )
{
return t.type() == GetValueType< bool >() || !!GetLLVMType( t );
}
llvm::Type* GetLLVMType( const Value& t )
{
if( !t.isType() )
return nullptr;
|
| ︙ | ︙ |
Changes to bs/builtins/types/template/unify.cpp.
1 2 3 4 5 6 7 8 9 10 |
#include "builtins/builtins.h"
using namespace goose;
using namespace goose::ir;
namespace goose::builtins
{
void SetupTemplateFunctionUnification( Env& e )
{
auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
| | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "builtins/builtins.h"
using namespace goose;
using namespace goose::ir;
namespace goose::builtins
{
void SetupTemplateFunctionUnification( Env& e )
{
auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( VA ) ) ) );
auto tFuncTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( texpr ), TSID( tfunc ),
ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );
// func type param / tfunc arg
e.unificationRuleSet()->addSymRule( URINFOS,
|
| ︙ | ︙ |
Changes to bs/builtins/types/tuple/lower.cpp.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 |
{
RecordType rt;
bool success = true;
ForEachInTupleType( tupType, [&]( auto&& t )
{
auto loweredType = LowerTypeForRuntime( c, t );
| | | > > > > > > | > > > > > > > > > > > > > > > > > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
{
RecordType rt;
bool success = true;
ForEachInTupleType( tupType, [&]( auto&& t )
{
auto loweredType = LowerTypeForRuntime( c, t );
if( !loweredType || loweredType->isPoison() )
{
success = false;
return false;
}
rt.m_memberTypes->append( ValueToIRExpr( *loweredType ) );
return true;
} );
if( !success )
return PoisonValue();
return ToValue( rt );
} );
RegisterBuiltinFunc< Intrinsic< Value ( CustomPattern< Value, TuplePattern > ) > >( e, e.extLowerConstantForRuntime(),
[]( const Context& c, const Value& tup )
{
auto types = make_shared< Vector >();
auto vals = make_shared< Vector >();
bool success = true;
ForEachInTuple( tup, [&]( auto&& t )
{
auto member = LowerConstantForRuntime( c, t );
if( !member || member->isPoison() )
{
success = false;
return false;
}
types->append( member->type() );
vals->append( ValueToIRExpr( *member ) );
return true;
} );
if( !success )
return PoisonValue();
return CreateRecord( move( types ), move( vals ), false );
} );
}
}
|
Changes to bs/codegen/address.cpp.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 18 |
if( !baseAddrVal )
return nullptr;
if( addr.path().empty() )
return baseAddrVal;
llvm::SmallVector< llvm::Value*, 4 > idxs;
for( auto&& index : addr.path() )
| > > | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
if( !baseAddrVal )
return nullptr;
if( addr.path().empty() )
return baseAddrVal;
llvm::SmallVector< llvm::Value*, 4 > idxs;
idxs.push_back( llvm::ConstantInt::get( llvm::Type::getInt32Ty( GetLLVMContext() ), 0 ) );
for( auto&& index : addr.path() )
idxs.push_back( llvm::ConstantInt::get( llvm::Type::getInt32Ty( GetLLVMContext() ), index ) );
return m_llvmBuilder.CreateGEP( baseAddrVal, idxs );
}
llvm::Value* Module::buildAddress( Infos& inf, const BaseAddress& baseAddr )
{
return visit( [&]( auto&& ba )
|
| ︙ | ︙ |
Changes to bs/codegen/instructions.cpp.
1 2 3 4 5 6 7 | #include "codegen.h" #include "builtins/builtins.h" using namespace goose; using namespace goose::codegen; using namespace goose::builtins; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include "codegen.h"
#include "builtins/builtins.h"
using namespace goose;
using namespace goose::codegen;
using namespace goose::builtins;
llvm::Value* Module::buildInstruction( Infos& inf, const llr::Instruction& instr )
{
return visit( [&]( auto&& e )
{
return buildInstruction( inf, e );
}, instr.content() );
}
|
| ︙ | ︙ | |||
138 139 140 141 142 143 144 145 |
auto* pAlloca = buildAlloca( inf, GetLLVMType( *type ) );
createTemporary( inf, av.index(), pAlloca );
return pAlloca;
}
llvm::Value* Module::buildInstruction( Infos& inf, const llr::Load& load )
{
auto* ptrVal = buildAddress( inf, load.addr() );
| > > > > > > > | > > > > > > > > > > > > > > > > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
auto* pAlloca = buildAlloca( inf, GetLLVMType( *type ) );
createTemporary( inf, av.index(), pAlloca );
return pAlloca;
}
llvm::Value* Module::buildInstruction( Infos& inf, const llr::Load& load )
{
auto type = LowerTypeForRuntime( inf.context, *ValueFromIRExpr( load.type() ) );
if( !type )
return nullptr;
auto* llvmType = GetLLVMType( *type );
assert( llvmType );
auto* ptrVal = buildAddress( inf, load.addr() );
return m_llvmBuilder.CreateLoad( llvmType, ptrVal );
}
llvm::Value* Module::buildInstruction( Infos& inf, const llr::Store& store )
{
auto* pValue = buildValue( inf, store.val() );
if( !pValue )
return nullptr;
auto* ptrVal = buildAddress( inf, store.addr() );
if( llvm::isa< llvm::ConstantAggregate >( pValue ) )
{
stringstream name;
name << ".constaggr" << hex << m_nextAggregateID++;
auto pGlob = new llvm::GlobalVariable( m_llvmModule,
pValue->getType(), true, llvm::GlobalValue::LinkageTypes::PrivateLinkage,
static_cast< llvm::Constant* >( pValue ), name.str() );
auto size = m_dataLayout.getTypeAllocSize( pValue->getType() );
return m_llvmBuilder.CreateMemCpy( ptrVal, llvm::None, pGlob, llvm::None,
llvm::ConstantInt::get( llvm::Type::getInt32Ty( GetLLVMContext() ), size ) );
}
return m_llvmBuilder.CreateStore( pValue, ptrVal );
}
llvm::Value* Module::buildInstruction( Infos& inf, const llr::Phi& p )
{
auto type = LowerTypeForRuntime( inf.context, p.type() );
if( !type )
|
| ︙ | ︙ |
Changes to bs/codegen/meson.build.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
goose_codegen = library( 'goose-codegen',
'codegen.cpp',
'module.cpp',
'func.cpp',
'mangle.cpp',
'basicblock.cpp',
'instructions.cpp',
'address.cpp',
'logicops.cpp',
'arithops.cpp',
'compareops.cpp',
include_directories: bsinc,
dependencies: fmt_dep
| > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
goose_codegen = library( 'goose-codegen',
'codegen.cpp',
'module.cpp',
'func.cpp',
'mangle.cpp',
'basicblock.cpp',
'instructions.cpp',
'value.cpp',
'address.cpp',
'logicops.cpp',
'arithops.cpp',
'compareops.cpp',
include_directories: bsinc,
dependencies: fmt_dep
|
| ︙ | ︙ |
Changes to bs/codegen/module.cpp.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include "llvm/IR/LegacyPassManager.h"
using namespace goose;
using namespace goose::codegen;
Module::Module( const string& name ) :
m_llvmModule( name, GetLLVMContext() ),
m_llvmBuilder( GetLLVMContext() )
{}
void Module::dumpAsLlvmIr( const string& filename ) const
{
error_code err;
llvm::raw_fd_ostream out( filename, err );
| > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include "llvm/IR/LegacyPassManager.h"
using namespace goose;
using namespace goose::codegen;
Module::Module( const string& name ) :
m_llvmModule( name, GetLLVMContext() ),
m_dataLayout( &m_llvmModule ),
m_llvmBuilder( GetLLVMContext() )
{}
void Module::dumpAsLlvmIr( const string& filename ) const
{
error_code err;
llvm::raw_fd_ostream out( filename, err );
|
| ︙ | ︙ |
Changes to bs/codegen/module.h.
| ︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
return m_llvmBuilder.GetInsertBlock()->getParent();
}
llvm::BasicBlock* buildCFG( Infos& inf, llvm::Function* llvmFunc, const ptr< llr::CFG >& pCFG );
llvm::BasicBlock* buildBasicBlock( Infos& inf, const ptr< llr::BasicBlock >& pBB );
llvm::Value* buildValue( Infos& inf, const Value& val );
llvm::Value* buildInstruction( Infos& inf, const llr::Instruction& instr );
llvm::Value* buildInstruction( Infos& inf, const llr::Call& call );
llvm::Value* buildInstruction( Infos& inf, const llr::CreateTemporary& ct );
llvm::Value* buildInstruction( Infos& inf, const llr::GetTemporary& gt );
llvm::Value* buildInstruction( Infos& inf, const llr::AllocVar& av );
llvm::Value* buildInstruction( Infos& inf, const llr::Load& load );
| > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
return m_llvmBuilder.GetInsertBlock()->getParent();
}
llvm::BasicBlock* buildCFG( Infos& inf, llvm::Function* llvmFunc, const ptr< llr::CFG >& pCFG );
llvm::BasicBlock* buildBasicBlock( Infos& inf, const ptr< llr::BasicBlock >& pBB );
llvm::Value* buildValue( Infos& inf, const Value& val );
llvm::Constant* buildConstant( Infos& inf, const Value& val );
llvm::Value* buildInstruction( Infos& inf, const llr::Instruction& instr );
llvm::Value* buildInstruction( Infos& inf, const llr::Call& call );
llvm::Value* buildInstruction( Infos& inf, const llr::CreateTemporary& ct );
llvm::Value* buildInstruction( Infos& inf, const llr::GetTemporary& gt );
llvm::Value* buildInstruction( Infos& inf, const llr::AllocVar& av );
llvm::Value* buildInstruction( Infos& inf, const llr::Load& load );
|
| ︙ | ︙ | |||
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
llvm::Value* buildAddress( Infos& inf, const TemporaryAddress& ta );
llvm::Value* buildAddress( Infos& inf, const VarAddress& va );
llvm::Value* buildAlloca( Infos& inf, llvm::Type* type );
llvm::Value* createTemporary( Infos& inf, uint32_t index, llvm::Value* pValue ) const;
llvm::Module m_llvmModule;
llvm::IRBuilder<> m_llvmBuilder;
llvm::TargetMachine* m_targetMachine = nullptr;
unordered_map< string, llvm::GlobalVariable* > m_strings;
};
}
#endif
| > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
llvm::Value* buildAddress( Infos& inf, const TemporaryAddress& ta );
llvm::Value* buildAddress( Infos& inf, const VarAddress& va );
llvm::Value* buildAlloca( Infos& inf, llvm::Type* type );
llvm::Value* createTemporary( Infos& inf, uint32_t index, llvm::Value* pValue ) const;
llvm::Module m_llvmModule;
llvm::DataLayout m_dataLayout;
llvm::IRBuilder<> m_llvmBuilder;
llvm::TargetMachine* m_targetMachine = nullptr;
unordered_map< string, llvm::GlobalVariable* > m_strings;
uint32_t m_nextAggregateID = 0;
};
}
#endif
|
Added bs/codegen/value.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include "codegen.h"
#include "builtins/builtins.h"
using namespace goose;
using namespace goose::codegen;
using namespace goose::builtins;
llvm::Value* Module::buildValue( Infos& inf, const Value& val )
{
if( val.isPoison() )
return nullptr;
if( val.isConstant() )
return buildConstant( inf, val );
return buildInstruction( inf, *val.llr() );
}
llvm::Constant* Module::buildConstant( Infos& inf, const Value& v )
{
assert( v.isConstant() );
auto val = LowerConstantForRuntime( inf.context, v );
if( !val )
return nullptr;
if( auto b = FromValue< bool >( *val ) )
{
return *b ?
llvm::ConstantInt::getTrue( GetLLVMContext() ) :
llvm::ConstantInt::getFalse( GetLLVMContext() );
}
else if( auto intVal = FromValue< APSInt >( *val ) )
{
return llvm::ConstantInt::get( GetLLVMType( *ValueFromIRExpr( val->type() ) ),
*FromValue< APSInt >( *val ) );
}
else if( auto ptType = FromValue< PointerType >( *ValueFromIRExpr( val->type() ) ) )
{
// The only kind of pointer constant we can have at the moment are nullptr.
return llvm::ConstantPointerNull::get( static_cast< llvm::PointerType* >
( GetLLVMType( *ValueFromIRExpr( val->type() ) ) ) );
}
else if( auto recType = FromValue< RecordType >( *ValueFromIRExpr( val->type() ) ) )
{
llvm::SmallVector< llvm::Constant*, 8 > members;
assert( holds_alternative< pvec >( val->val() ) );
bool success = true;
ForEachInVectorTerm( val->val(), [&]( auto&& t )
{
auto* pMemberVal = buildConstant( inf, *ValueFromIRExpr( t ) );
if( !pMemberVal )
{
success = false;
return false;
}
members.push_back( pMemberVal );
return true;
} );
if( !success )
return nullptr;
return llvm::ConstantStruct::get( static_cast< llvm::StructType* >
( GetLLVMType( *ValueFromIRExpr( val->type() ) ) ), members );
}
DiagnosticsManager::GetInstance().emitErrorMessage(
v.locationId(), "constants with compile time types are not supported.", 0 );
return nullptr;
}
|
Changes to bs/sema/env.h.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
auto& extDestroyValue() { return m_extDestroyValue; }
const auto& extDestroyValue() const { return m_extDestroyValue; }
auto& extLowerTypeForRuntime() { return m_extLowerTypeForRuntime; }
const auto& extLowerTypeForRuntime() const { return m_extLowerTypeForRuntime; }
auto& extInitialize() { return m_extInitializeLocalVar; }
const auto& extInitialize() const { return m_extInitializeLocalVar; }
template< typename... T >
auto createLLRFunc( T&&... args )
{
ms_llrFuncs.emplace_back( make_shared< llr::Func >( forward< T >( args )... ) );
return ms_llrFuncs.back();
}
private:
Trie< ptr< ValueProvider > > m_valueStore;
ptr< TemplateRuleSet > m_templateRuleSet;
ptr< InvocationRuleSet > m_invocationRuleSet;
ptr< UnificationRuleSet > m_unificationRuleSet;
ptr< OverloadSet > m_extDropValue;
ptr< OverloadSet > m_extDestroyValue;
ptr< OverloadSet > m_extLowerTypeForRuntime;
ptr< OverloadSet > m_extInitializeLocalVar;
uint64_t m_valueStoreVersion = 0;
ptr< CTMemoryManager > m_memManager;
// LLR funcs form a cyclic graph, since functions can
| > > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
auto& extDestroyValue() { return m_extDestroyValue; }
const auto& extDestroyValue() const { return m_extDestroyValue; }
auto& extLowerTypeForRuntime() { return m_extLowerTypeForRuntime; }
const auto& extLowerTypeForRuntime() const { return m_extLowerTypeForRuntime; }
auto& extLowerConstantForRuntime() { return m_extLowerConstantForRuntime; }
const auto& extLowerConstantForRuntime() const { return m_extLowerConstantForRuntime; }
auto& extInitialize() { return m_extInitializeLocalVar; }
const auto& extInitialize() const { return m_extInitializeLocalVar; }
template< typename... T >
auto createLLRFunc( T&&... args )
{
ms_llrFuncs.emplace_back( make_shared< llr::Func >( forward< T >( args )... ) );
return ms_llrFuncs.back();
}
private:
Trie< ptr< ValueProvider > > m_valueStore;
ptr< TemplateRuleSet > m_templateRuleSet;
ptr< InvocationRuleSet > m_invocationRuleSet;
ptr< UnificationRuleSet > m_unificationRuleSet;
ptr< OverloadSet > m_extDropValue;
ptr< OverloadSet > m_extDestroyValue;
ptr< OverloadSet > m_extLowerTypeForRuntime;
ptr< OverloadSet > m_extLowerConstantForRuntime;
ptr< OverloadSet > m_extInitializeLocalVar;
uint64_t m_valueStoreVersion = 0;
ptr< CTMemoryManager > m_memManager;
// LLR funcs form a cyclic graph, since functions can
|
| ︙ | ︙ |
Changes to bs/sema/lower.cpp.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 |
return type;
DiagnosticsContext dc( type.locationId(), "When invoking LowerTypeForRuntime." );
auto result = InvokeOverloadSet( c, c.env()->extLowerTypeForRuntime(), AppendToTuple( EmptyTuple(), type ) );
if( result.isPoison() || !IsRuntimeType( result ) )
return nullopt;
return result;
}
}
| > > > > > > > > > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
return type;
DiagnosticsContext dc( type.locationId(), "When invoking LowerTypeForRuntime." );
auto result = InvokeOverloadSet( c, c.env()->extLowerTypeForRuntime(), AppendToTuple( EmptyTuple(), type ) );
if( result.isPoison() || !IsRuntimeType( result ) )
return nullopt;
return result;
}
optional< Value > LowerConstantForRuntime( const Context& c, const Value& val )
{
if( val.type() == GetValueType< bool >() || IsRuntimeType( *ValueFromIRExpr( val.type() ) ) )
return val;
DiagnosticsContext dc( val.locationId(), "When invoking LowerConstantForRuntime." );
auto result = InvokeOverloadSet( c, c.env()->extLowerConstantForRuntime(), AppendToTuple( EmptyTuple(), val ) );
if( result.isPoison() || !IsRuntimeType( *ValueFromIRExpr( result.type() ) ) )
return nullopt;
return result;
}
}
|
Changes to bs/sema/sema.h.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{
using namespace util;
using namespace ir;
using namespace diagnostics;
class Context;
extern optional< Value > LowerTypeForRuntime( const Context& c, const Value& type );
}
#include "hole.h"
#include "domain.h"
#include "context.h"
#include "ctmm.h"
#include "env.h"
| > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{
using namespace util;
using namespace ir;
using namespace diagnostics;
class Context;
extern optional< Value > LowerTypeForRuntime( const Context& c, const Value& type );
extern optional< Value > LowerConstantForRuntime( const Context& c, const Value& val );
}
#include "hole.h"
#include "domain.h"
#include "context.h"
#include "ctmm.h"
#include "env.h"
|
| ︙ | ︙ |
Changes to tests/noprelude/codegen/bitwiseops.ll.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | %8 = alloca i16 store i8 %0, i8* %5 store i8 %1, i8* %6 store i16 %2, i16* %7 store i16 %3, i16* %8 %9 = load i8, i8* %5 %10 = load i8, i8* %6 | | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | %8 = alloca i16 store i8 %0, i8* %5 store i8 %1, i8* %6 store i16 %2, i16* %7 store i16 %3, i16* %8 %9 = load i8, i8* %5 %10 = load i8, i8* %6 %11 = call i8 @"_3R_4Rs2:g0s6:lomarf_3R_2_5Vr_5Vo_3ti0_4s7:integerPp_2i8i0hs1:__5Vr_5Vo_3ti0_4$2Pp_2i8i0h$3_5Vo_3ti0_4$2Pp_2i8i0_5Vo_3ti0_7up_2qR_5Vo_3ti0_4$2Pp_2i8i0_2q_2_5Vr_5Vo_3ti0_4$2Pp_2i8i0h$3_5Vr_5Vo_3ti0_4$2Pp_2i8i0h$3Pi0"(i8 %9, i8 %10) %12 = load i16, i16* %8 %13 = call i16 @"_3R_4Rs2:g0s6:lomarf_3R_2_5Vr_5Vo_3ti0_4s7:integerPp_2i10i1hs1:__5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3_5Vo_3ti0_4$2Pp_2i10i1_5Vo_3ti0_7up_2qR_5Vo_3ti0_4$2Pp_2i10i1_2q_2_5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3_5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3Pi0"(i16 219, i16 %12) %14 = load i16, i16* %8 %15 = call i16 @"_3R_4Rs2:g0s6:lomarf_3R_2_5Vr_5Vo_3ti0_4s7:integerPp_2i10i1hs1:__5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3_5Vo_3ti0_4$2Pp_2i10i1_5Vo_3ti0_7up_2qR_5Vo_3ti0_4$2Pp_2i10i1_2q_2_5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3_5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3Pi0"(i16 %14, i16 69) %16 = load i8, i8* %5 %17 = load i8, i8* %6 %18 = xor i8 %16, %17 %19 = load i16, i16* %7 %20 = load i16, i16* %8 %21 = xor i16 %19, %20 %22 = load i16, i16* %7 |
| ︙ | ︙ | |||
42 43 44 45 46 47 48 | %38 = load i16, i16* %7 %39 = shl i16 %38, 4 %40 = load i16, i16* %7 %41 = ashr i16 %40, 4 ret void } | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
%38 = load i16, i16* %7
%39 = shl i16 %38, 4
%40 = load i16, i16* %7
%41 = ashr i16 %40, 4
ret void
}
define private i8 @"_3R_4Rs2:g0s6:lomarf_3R_2_5Vr_5Vo_3ti0_4s7:integerPp_2i8i0hs1:__5Vr_5Vo_3ti0_4$2Pp_2i8i0h$3_5Vo_3ti0_4$2Pp_2i8i0_5Vo_3ti0_7up_2qR_5Vo_3ti0_4$2Pp_2i8i0_2q_2_5Vr_5Vo_3ti0_4$2Pp_2i8i0h$3_5Vr_5Vo_3ti0_4$2Pp_2i8i0h$3Pi0"(i8 %0, i8 %1) {
%3 = alloca i8
%4 = alloca i8
store i8 %0, i8* %3
store i8 %1, i8* %4
%5 = load i8, i8* %3
%6 = load i8, i8* %4
%7 = xor i8 %5, %6
ret i8 %7
}
define private i16 @"_3R_4Rs2:g0s6:lomarf_3R_2_5Vr_5Vo_3ti0_4s7:integerPp_2i10i1hs1:__5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3_5Vo_3ti0_4$2Pp_2i10i1_5Vo_3ti0_7up_2qR_5Vo_3ti0_4$2Pp_2i10i1_2q_2_5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3_5Vr_5Vo_3ti0_4$2Pp_2i10i1h$3Pi0"(i16 %0, i16 %1) {
%3 = alloca i16
%4 = alloca i16
store i16 %0, i16* %3
store i16 %1, i16* %4
%5 = load i16, i16* %3
%6 = load i16, i16* %4
%7 = xor i16 %5, %6
ret i16 %7
}
|
Changes to tests/noprelude/codegen/func.ll.
1 2 3 4 5 6 7 8 9 10 11 |
; ModuleID = 'testfuncmodule'
source_filename = "testfuncmodule"
@.str0 = private constant [7 x i8] c"lomarf\00"
@.str1 = private constant [9 x i8] c"whatever\00"
define void @main(i1 %0) {
%2 = alloca i1
store i1 %0, i1* %2
%3 = load i1, i1* %2
%4 = xor i1 %3, true
| | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
; ModuleID = 'testfuncmodule'
source_filename = "testfuncmodule"
@.str0 = private constant [7 x i8] c"lomarf\00"
@.str1 = private constant [9 x i8] c"whatever\00"
define void @main(i1 %0) {
%2 = alloca i1
store i1 %0, i1* %2
%3 = load i1, i1* %2
%4 = xor i1 %3, true
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_1_5Vr_5Vo_3ti0_3s4:boolPph$2Pi0"(i1 %4)
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_1_5Vr_5Vo_3ti0_4s7:pointerPp_5Vo_3ti0_4s7:integerPp_2i8i0h$2Pi0"(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str1, i8 0, i8 0))
call void @lomarf(i32 219)
ret void
}
define private void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_1_5Vr_5Vo_3ti0_3s4:boolPph$2Pi0"(i1 %0) {
%2 = alloca i1
store i1 %0, i1* %2
call void @puts(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str0, i8 0, i8 0))
ret void
}
declare void @puts(i8*)
define private void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_1_5Vr_5Vo_3ti0_4s7:pointerPp_5Vo_3ti0_4s7:integerPp_2i8i0h$2Pi0"(i8* %0) {
%2 = alloca i8*
store i8* %0, i8** %2
%3 = load i8*, i8** %2
call void @puts(i8* %3)
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_1_5Vr_5Vo_3ti0_3s4:boolPph$2Pi0"(i1 true)
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_1_5Vr_5Vo_3ti0_3s4:boolPph$2Pi0"(i1 false)
ret void
}
declare void @lomarf(i32)
|
Changes to tests/noprelude/codegen/if.ll.
1 2 3 4 5 6 7 8 9 |
; ModuleID = 'iftest'
source_filename = "iftest"
@.str0 = private constant [7 x i8] c"lomarf\00"
@.str1 = private constant [3 x i8] c"gg\00"
@.str2 = private constant [5 x i8] c"blah\00"
@.str3 = private constant [4 x i8] c"lol\00"
define void @main() {
| | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
; ModuleID = 'iftest'
source_filename = "iftest"
@.str0 = private constant [7 x i8] c"lomarf\00"
@.str1 = private constant [3 x i8] c"gg\00"
@.str2 = private constant [5 x i8] c"blah\00"
@.str3 = private constant [4 x i8] c"lol\00"
define void @main() {
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_2_5Vr_5Vo_3ti0_3s4:boolPph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 true, i1 false)
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_2_5Vr_5Vo_3ti0_3s4:boolPph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 true, i1 true)
call void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_2_5Vr_5Vo_3ti0_3s4:boolPph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 false, i1 false)
ret void
}
define private void @"_3R_3xs2:g0s3:meh_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0v_2q_2_5Vr_5Vo_3ti0_3s4:boolPph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 %0, i1 %1) {
%3 = alloca i1
%4 = alloca i1
store i1 %0, i1* %3
store i1 %1, i1* %4
%5 = load i1, i1* %3
br i1 %5, label %6, label %12
|
| ︙ | ︙ |
Changes to tests/noprelude/codegen/logicops.ll.
1 2 3 4 5 6 7 8 9 10 |
; ModuleID = 'logic ops test'
source_filename = "logic ops test"
define void @main(i1 %0, i1 %1) {
%3 = alloca i1
%4 = alloca i1
store i1 %0, i1* %3
store i1 %1, i1* %4
%5 = load i1, i1* %3
%6 = load i1, i1* %4
| | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
; ModuleID = 'logic ops test'
source_filename = "logic ops test"
define void @main(i1 %0, i1 %1) {
%3 = alloca i1
%4 = alloca i1
store i1 %0, i1* %3
store i1 %1, i1* %4
%5 = load i1, i1* %3
%6 = load i1, i1* %4
%7 = call i1 @"_3R_3xs2:g0s6:lomarf_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0_3s4:boolPp_2q_2_5Vr_5Vo_3ti0_3$3Pph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 %5, i1 %6)
%8 = load i1, i1* %3
%9 = load i1, i1* %4
%10 = call i1 @"_3R_3xs2:g0s4:blah_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0_3s4:boolPp_2q_2_5Vr_5Vo_3ti0_3$3Pph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 %8, i1 %9)
ret void
}
define private i1 @"_3R_3xs2:g0s6:lomarf_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0_3s4:boolPp_2q_2_5Vr_5Vo_3ti0_3$3Pph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 %0, i1 %1) {
%3 = alloca i1
%4 = alloca i1
store i1 %0, i1* %3
store i1 %1, i1* %4
%5 = load i1, i1* %3
br i1 %5, label %8, label %6
6: ; preds = %2
%7 = load i1, i1* %4
br label %8
8: ; preds = %6, %2
%9 = phi i1 [ true, %2 ], [ %7, %6 ]
ret i1 %9
}
define private i1 @"_3R_3xs2:g0s4:blah_5Vo_3ti0_7up_2qhs1:__5Vo_3ti0_3s4:boolPp_2q_2_5Vr_5Vo_3ti0_3$3Pph$2_5Vr_5Vo_3ti0_3$3Pph$2Pi0"(i1 %0, i1 %1) {
%3 = alloca i1
%4 = alloca i1
store i1 %0, i1* %3
store i1 %1, i1* %4
%5 = load i1, i1* %3
br i1 %5, label %6, label %8
|
| ︙ | ︙ |
Changes to tests/noprelude/combined/meson.build.
1 | tests = [ | | | 1 2 3 4 5 6 7 8 9 |
tests = [
'tuple',
'mandelbrot'
]
testrunner_interp = find_program( 'test_runner_interp.sh' )
testrunner_compile = find_program( 'test_runner_compile.sh' )
foreach t : tests
|
| ︙ | ︙ |
Changes to tests/noprelude/combined/test_runner_compile.sh.
1 | #!/bin/sh | | | 1 2 3 4 5 6 7 8 9 |
#!/bin/sh
OUTFILE=FUCK.txt #$(mktemp)
$1 $2.g
if [ "$?" -eq "1" ]; then
exit 1
fi
$2.g.out > $OUTFILE
|
| ︙ | ︙ |
Changes to tests/noprelude/combined/tuple.g.
|
| > | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using puts = ExternalVarArgFunction( uint(32) ( pointer( uint(8) ) str ), "printf" )
void print( $str )
{
#if IsCompiling
{
puts( $str )
}
#else
{
Print( $str )
}
}
bool check( bool cond, $message )
{
print( $message )
print( ": " )
if cond print( "OK\n" ) else print( "Failed\n" )
return cond
}
// Multiple return values
bool, uint(32) foo()
|
| ︙ | ︙ | |||
43 44 45 46 47 48 49 |
return 1
// Modifying individual tuple members
tup2.2 = 654654
if !check( tup2.0 == 219 & tup2.1 & tup2.2 == 654654 & tup2.3 == 420, "tuple test 3" )
return 1
| > > > > > > > > > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
return 1
// Modifying individual tuple members
tup2.2 = 654654
if !check( tup2.0 == 219 & tup2.1 & tup2.2 == 654654 & tup2.3 == 420, "tuple test 3" )
return 1
using fflush = ExternalFunction( uint(32) ( pointer(void) stream ), "fflush" )
#if IsCompiling
{
fflush( nullptr )
}
#else
{
FlushOutput();
}
|