Goose  Diff

Differences From Artifact [e8a14395e3]:

  • File bs/codegen/module.h — part of check-in [68260b65f2] at 2022-03-14 19:23:09 on branch trunk —
    • bracket blocks inlined in the code are no longer proposition lists but a new type of block to contain "ghost code" (ie a verification specific cfg)
    • added a GhostBranch instruction to insert the above in the middle of regular code
    • removed a bunch of hacks to ignore load/stores involving ghost funcs during execution and codegen since they are now separated from normal code using the above
    • miscellaneous other refactorings and improvements
    • as a result ghost code is now more flexible and can use idiomatic tuple assignments to exchange the values of two ghost function closures
    (user: zlodo size: 6332)

To Artifact [e87e65a5e4]:

  • File bs/codegen/module.h — part of check-in [dd5c48041c] at 2022-05-26 11:31:44 on branch cir-stack-language — Re-enabled codegen and related tests, and adapted it to the now stack-based CIR language (user: zlodo size: 6444)

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
81
82
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
            llvm::Function* getOrCreateFunc( const Context& c, const builtins::Func& func, const string& name,
                llvm::Function::LinkageTypes linkageType );

            void runOptimizationPasses();
            bool emitToFile( const string& filename, llvm::CodeGenFileType type );

        private:
            struct Infos
            {

                Infos( const Context& c ) : context( c ) {}



                const Context& context;


                llvm::BasicBlock* allocaBasicBlock = nullptr;
                llvm::AllocaInst* lastEmittedAlloca = nullptr;

                using storage_type = cir::TempStorage< NullInit< llvm::Value* > >;
                ptr< storage_type > temporaries = make_shared< storage_type >();


            };



            llvm::Function* getCurrentFunction() const
            {
                return m_llvmBuilder.GetInsertBlock()->getParent();
            }

            llvm::BasicBlock* buildCFG( Infos& inf, llvm::Function* llvmFunc, const ptr< cir::CFG >& pCFG );
            llvm::BasicBlock* buildBasicBlock( Infos& inf, const ptr< cir::BasicBlock >& pBB );

            llvm::Value* buildValue( Infos& inf, const Value& val );
            llvm::Constant* buildConstant( Infos& inf, const Value& val );
            llvm::Constant* buildConstantPointer( Infos& inf, const builtins::PointerType& ptType, const Value& v );


            llvm::Value* buildInstruction( Infos& inf, const cir::Instruction& instr );
            llvm::Value* buildInstruction( Infos& inf, const monostate& );
            llvm::Value* buildInstruction( Infos& inf, const cir::Call& call );

            llvm::Value* buildInstruction( Infos& inf, const cir::VarAddr& va );
            llvm::Value* buildInstruction( Infos& inf, const cir::TempAddr& ta );
            llvm::Value* buildInstruction( Infos& inf, const cir::Select& s );
            llvm::Value* buildInstruction( Infos& inf, const cir::CreateTemporary& ct );
            llvm::Value* buildInstruction( Infos& inf, const cir::GetTemporary& gt );
            llvm::Value* buildInstruction( Infos& inf, const cir::AllocVar& av );
            llvm::Value* buildInstruction( Infos& inf, const cir::Load& load );
            llvm::Value* buildInstruction( Infos& inf, const cir::Store& store );
            llvm::Value* buildInstruction( Infos& inf, const cir::Phi& p );

            llvm::Value* buildInstruction( Infos& inf, const cir::Not& uo );
            llvm::Value* buildInstruction( Infos& inf, const cir::And& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::Or& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::Xor& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::Implies& bo );

            llvm::Value* buildInstruction( Infos& inf, const cir::Shl& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::LShr& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::AShr& bo );

            llvm::Value* buildInstruction( Infos& inf, const cir::Add& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::Sub& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::Mul& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::UDiv& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::SDiv& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::URem& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::SRem& bo );

            llvm::Value* buildInstruction( Infos& inf, const cir::Eq& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::Neq& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::UGT& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::UGE& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::ULT& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::ULE& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::SGT& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::SGE& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::SLT& bo );
            llvm::Value* buildInstruction( Infos& inf, const cir::SLE& bo );

            llvm::Value* buildInstruction( Infos& inf, const cir::Assert& ass );
            llvm::Value* buildInstruction( Infos& inf, const cir::Placeholder& ph );
            llvm::Value* buildInstruction( Infos& inf, const cir::PHOverride& pho );
            llvm::Value* buildInstruction( Infos& inf, const cir::GhostCall& gc );

            bool buildTerminator( Infos& inf, const cir::Terminator& terminator );

            bool buildTerminator( Infos& inf, const cir::Ret& r );
            bool buildTerminator( Infos& inf, const cir::Branch& b );
            bool buildTerminator( Infos& inf, const cir::CondBranch& cb );
            bool buildTerminator( Infos& inf, const cir::GhostBranch& gb );

            template< typename T >
            bool buildTerminator( Infos& inf, const T& t )
            {
                return false;
            }

            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;







|

>
|
>
>
>


>





>
>

>
>






|
|

|
|
|

>
|
|
|
>
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
>
|
|
|
|


|




|
|







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
81
82
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
131
132
133
134
135
            llvm::Function* getOrCreateFunc( const Context& c, const builtins::Func& func, const string& name,
                llvm::Function::LinkageTypes linkageType );

            void runOptimizationPasses();
            bool emitToFile( const string& filename, llvm::CodeGenFileType type );

        private:
            struct State
            {
                State( const Context& c, llvm::Function* f ) :
                    context( c ),
                    llvmFunc( f )
                {}

                const Context& context;

                llvm::Function* llvmFunc = nullptr;
                llvm::BasicBlock* allocaBasicBlock = nullptr;
                llvm::AllocaInst* lastEmittedAlloca = nullptr;

                using storage_type = cir::TempStorage< NullInit< llvm::Value* > >;
                ptr< storage_type > temporaries = make_shared< storage_type >();

                Stack stack;
            };

            static llvm::BasicBlock* GetOrCreateLLVMBB( State& st, const ptr< cir::BasicBlock >& pBB );

            llvm::Function* getCurrentFunction() const
            {
                return m_llvmBuilder.GetInsertBlock()->getParent();
            }

            llvm::BasicBlock* buildCFG( State& st, llvm::Function* llvmFunc, const ptr< cir::CFG >& pCFG );
            llvm::BasicBlock* buildBasicBlock( State& st, const ptr< cir::BasicBlock >& pBB );

            llvm::Value* buildValue( State& st, const Value& val );
            llvm::Constant* buildConstant( State& st, const Value& val );
            llvm::Constant* buildConstantPointer( State& st, const builtins::PointerType& ptType, const Value& v );

            bool buildInstruction( State& st, const cir::InstrSeq& is );
            bool buildInstruction( State& st, const cir::Instruction& instr );
            bool buildInstruction( State& st, const monostate& );
            bool buildInstruction( State& st, const cir::Call& call );
            bool buildInstruction( State& st, const cir::Constant& ct );
            bool buildInstruction( State& st, const cir::VarAddr& va );
            bool buildInstruction( State& st, const cir::TempAddr& ta );
            bool buildInstruction( State& st, const cir::Select& s );
            bool buildInstruction( State& st, const cir::CreateTemporary& ct );
            bool buildInstruction( State& st, const cir::GetTemporary& gt );
            bool buildInstruction( State& st, const cir::AllocVar& av );
            bool buildInstruction( State& st, const cir::Load& load );
            bool buildInstruction( State& st, const cir::Store& store );
            bool buildInstruction( State& st, const cir::Phi& p );

            bool buildInstruction( State& st, const cir::Not& uo );
            bool buildInstruction( State& st, const cir::And& bo );
            bool buildInstruction( State& st, const cir::Or& bo );
            bool buildInstruction( State& st, const cir::Xor& bo );
            bool buildInstruction( State& st, const cir::Implies& bo );

            bool buildInstruction( State& st, const cir::Shl& bo );
            bool buildInstruction( State& st, const cir::LShr& bo );
            bool buildInstruction( State& st, const cir::AShr& bo );

            bool buildInstruction( State& st, const cir::Add& bo );
            bool buildInstruction( State& st, const cir::Sub& bo );
            bool buildInstruction( State& st, const cir::Mul& bo );
            bool buildInstruction( State& st, const cir::UDiv& bo );
            bool buildInstruction( State& st, const cir::SDiv& bo );
            bool buildInstruction( State& st, const cir::URem& bo );
            bool buildInstruction( State& st, const cir::SRem& bo );

            bool buildInstruction( State& st, const cir::Eq& bo );
            bool buildInstruction( State& st, const cir::Neq& bo );
            bool buildInstruction( State& st, const cir::UGT& bo );
            bool buildInstruction( State& st, const cir::UGE& bo );
            bool buildInstruction( State& st, const cir::ULT& bo );
            bool buildInstruction( State& st, const cir::ULE& bo );
            bool buildInstruction( State& st, const cir::SGT& bo );
            bool buildInstruction( State& st, const cir::SGE& bo );
            bool buildInstruction( State& st, const cir::SLT& bo );
            bool buildInstruction( State& st, const cir::SLE& bo );

            bool buildInstruction( State& st, const cir::Assert& ass );
            bool buildInstruction( State& st, const cir::Placeholder& ph );
            bool buildInstruction( State& st, const cir::PHOverride& pho );
            bool buildInstruction( State& st, const cir::GhostCall& gc );

            bool buildTerminator( State& st, const cir::Terminator& terminator );
            bool buildTerminator( State& st, const cir::RetVoid& r );
            bool buildTerminator( State& st, const cir::Ret& r );
            bool buildTerminator( State& st, const cir::Branch& b );
            bool buildTerminator( State& st, const cir::CondBranch& cb );
            bool buildTerminator( State& st, const cir::GhostBranch& gb );

            template< typename T >
            bool buildTerminator( State& st, const T& t )
            {
                return false;
            }

            llvm::Value* buildAlloca( State& st, llvm::Type* type );
            llvm::Value* createTemporary( State& st, 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;