compiler: Check SSA merge construction

3122b8f773d97914d63aefe4d37e3bb16f9ac51c9fa8d67a2bfa10b22fece608
Alexis Sellier committed ago 1 parent df26efaa
lib/std/lang/lower.rad +8 -3
3019 3019
            set self.blockData[*block].vars[*v] = val; // Cache.
3020 3020
            return val;
3021 3021
        }
3022 3022
        case VarSource::Merge => {
3023 3023
            unsafe {
3024 -
                return try createBlockParam(self, block, v);
3024 +
                let allocator = alloc::arenaAllocator(self.arena);
3025 +
                return try createBlockParam(self, block, v, allocator);
3025 3026
            }
3026 3027
        },
3027 3028
        case VarSource::Invalid => throw LowerError::InvalidUse,
3028 3029
    }
3029 3030
}
3113 3114
///     @end(w32 %1)              // x = %1, merged from predecessors
3114 3115
///       ret %1;
3115 3116
///
3116 3117
/// Create a register `%1` as a block parameter. In a sealed block, patch each
3117 3118
/// predecessor's jump to pass its value of `x`. Otherwise, defer until sealing.
3118 -
unsafe fn createBlockParam 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId, v: Var) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
3119 +
fn createBlockParam 'arena 'phase 'function (
3120 +
    self: &mut FnLowerer 'arena 'phase 'function,
3121 +
    block: BlockId,
3122 +
    v: Var,
3123 +
    allocator: alloc::Allocator
3124 +
) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
3119 3125
    // Entry block must not have block parameters.
3120 3126
    assert block <> self.entryBlock, "createBlockParam: entry block must not have block parameters";
3121 3127
    // Allocate a register to hold the merged value.
3122 3128
    let reg = nextReg(self);
3123 3129
    let type = getVar(&self.vars, v).type;
3124 3130
3125 3131
    // Create block parameter and add it to the block.
3126 3132
    let param = il::Param { value: reg, type };
3127 -
    let allocator = alloc::arenaAllocator(self.arena);
3128 3133
    let paramIdx = bindBlockParam(&mut self.blockData[*block], param, v, allocator);
3129 3134
3130 3135
    if self.blockData[*block].sealState == Sealed::Yes {
3131 3136
        // Block sealed: check for trivial phi before committing. If all
3132 3137
        // predecessors provide the same value, we can remove the param we