ir: new pass iteration strategy
Before: * IR basic blocks are in arbitrary order * when doing an IR pass, when a block is encountered, code must look at all the instructions in the old basic block, determine what blocks are referenced, and queue up those old basic blocks first. * This had a bug (See #667) Now: * IR basic blocks are required to be in an order that guarantees they will be referenced by a branch, before any instructions within are referenced. ir pass1 is updated to meet this constraint. * When doing an IR pass, we iterate over old basic blocks in the order they appear. Blocks which have not been referenced are discarded. * After the pass is complete, we must iterate again to look for old basic blocks which now point to incomplete new basic blocks, due to comptime code generation. * This last part can probably be optimized - most of the time we don't need to iterate over the basic block again. closes #667
This commit is contained in:
parent
aafb832288
commit
0ea50b3157
1428
src/ir.cpp
1428
src/ir.cpp
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,6 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
|
||||
switch (state) {
|
||||
State.Start => switch (c) {
|
||||
'{' => {
|
||||
// TODO if you make this an if statement with `and` then it breaks
|
||||
if (start_index < i) {
|
||||
%return output(context, fmt[start_index..i]);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ fn acos32(x: f32) -> f32 {
|
||||
if (hx >> 31 != 0) {
|
||||
return 2.0 * pio2_hi + 0x1.0p-120;
|
||||
} else {
|
||||
return 0;
|
||||
return 0.0;
|
||||
}
|
||||
} else {
|
||||
return math.nan(f32);
|
||||
|
@ -230,20 +230,21 @@ fn foo(args: ...) {
|
||||
|
||||
|
||||
test "peer type resolution: error and [N]T" {
|
||||
assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
|
||||
comptime assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
|
||||
// TODO: implicit %T to %U where T can implicitly cast to U
|
||||
//assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
|
||||
//comptime assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
|
||||
|
||||
assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
|
||||
comptime assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
|
||||
}
|
||||
|
||||
error BadValue;
|
||||
fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
|
||||
return switch (x) {
|
||||
0x00 => "OK",
|
||||
else => error.BadValue,
|
||||
};
|
||||
}
|
||||
//fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
|
||||
// return switch (x) {
|
||||
// 0x00 => "OK",
|
||||
// else => error.BadValue,
|
||||
// };
|
||||
//}
|
||||
fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {
|
||||
return switch (x) {
|
||||
0x00 => "OK",
|
||||
|
@ -560,3 +560,14 @@ fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {
|
||||
var a = ptr;
|
||||
return a;
|
||||
}
|
||||
|
||||
test "comptime if inside runtime while which unconditionally breaks" {
|
||||
testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
|
||||
comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
|
||||
}
|
||||
fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) {
|
||||
while (cond) {
|
||||
if (false) { }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user