New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
newCTFE rebase-dump #14243
base: master
Are you sure you want to change the base?
newCTFE rebase-dump #14243
Conversation
Thanks for your pull request, @maxhaton! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#14243" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review round on fpconv_ctfe.d
src/dmd/ctfe/fpconv_ctfe.d
Outdated
int exp; | ||
}; | ||
|
||
enum seperate_arrays = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note sure why this is needed. IMO, just pick a value.
src/dmd/ctfe/fpconv_ctfe.d
Outdated
enum npowers = 87; | ||
enum steppowers = 8; | ||
enum firstpower = -348; /* 10 ^ -348 */ | ||
|
||
enum expmax = -32; | ||
enum expmin = -60; | ||
|
||
enum expbits = 11; // 64 - 1 /*for signbit*/ - fracbits; | ||
enum fracbits = 52; | ||
|
||
enum fracmask = (1UL << fracbits) - 1; | ||
enum hiddenbit = (1UL << fracbits); | ||
enum expmask = ((1UL << expbits) - 1) << fracbits; | ||
enum signbit = (1UL << (double.sizeof * 8) -1); // 1 << (64 - 1) | ||
enum expbias = (((1 << (expbits - 1)) -1) + fracbits); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should be members of Fp
src/dmd/ctfe/fpconv_ctfe.d
Outdated
return bits; | ||
} | ||
|
||
Fp build_fp(double d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a constructor of Fp
src/dmd/ctfe/fpconv_ctfe.d
Outdated
static assert(build_double(Fp(9007199254740991LU, 971)) == double.max); | ||
static assert(() { return build_double(build_fp(double.max)); } () == double.max); | ||
|
||
void normalize(Fp* fp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a method
src/dmd/ctfe/fpconv_ctfe.d
Outdated
fp.exp -= shift; | ||
} | ||
|
||
void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a method and lower
and upper
should be out
src/dmd/ctfe/fpconv_ctfe.d
Outdated
lower.exp = upper.exp; | ||
} | ||
|
||
Fp multiply(const Fp* a, const Fp* b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be opBinary!("*")
src/dmd/ctfe/fpconv_ctfe.d
Outdated
} | ||
} | ||
|
||
static int grisu2(double d, char* digits, int* K) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these static
functions should be private
src/dmd/ctfe/fpconv_ctfe.d
Outdated
return generate_digits(&w, &upper, &lower, digits, K); | ||
} | ||
|
||
static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review round for ctfe/bc.d
src/dmd/ctfe/bc.d
Outdated
} +/ | ||
|
||
|
||
static if (is(typeof({import dmd.globals : Loc; }))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume this will always be true for building dmd. Why is this a thing?
src/dmd/ctfe/bc.d
Outdated
static assert(!bc_order_errors.length, bc_order_errors); | ||
|
||
|
||
pragma(msg, 2 ^^ 7 - LongInst.max, " opcodes remaining"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put this behind a debug static if
of some kind, or just make it a static assert
src/dmd/ctfe/bc.d
Outdated
Compiled, | ||
} | ||
|
||
//static if (is(typeof(() { import dmd.declaration : FuncDeclaration; }))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
src/dmd/ctfe/bc.d
Outdated
|
||
struct BCFunction | ||
{ | ||
void* funcDecl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this always a FuncDeclaration
? if it is the type should reflect this.
src/dmd/ctfe/bc.d
Outdated
} | ||
} | ||
|
||
extern (D) BCValue genLocal(BCType bct, string name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this explicitly marked extern(D)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because it uses the string
type which will die with the default extern(C++)
used for visitors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its not part of a visitor interface though. I don't follow.
src/dmd/ctfe/bc.d
Outdated
emitLongInst(LongInst.HeapStore8, _to.stackAddr, value.stackAddr); | ||
} | ||
|
||
void Load16(BCValue _to, BCValue from) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these LoadNN
and StoreNN
look very similar, there should probably be a common definition.
src/dmd/ctfe/bc.d
Outdated
|
||
BCValue pushOntoStack(BCValue val) | ||
{ | ||
if (!__ctfe) debug { import std.stdio; writeln("pushOntoStack: ", val); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std
usage
src/dmd/ctfe/bc.d
Outdated
{ | ||
case LongInst.SetHighImm32: | ||
{ | ||
result ~= "SetHigh " ~ localName(stackMap, lw >> 16) ~ ", #" ~ itos(hi) ~ "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this switch could be less cluttered with a local string function(string, uint)
foo("SetHigh ",hi)
src/dmd/ctfe/bc.d
Outdated
} | ||
break; | ||
|
||
case LongInst.Jmp: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto for the jump instructions
src/dmd/ctfe/bc.d
Outdated
__gshared int[ushort.max * 2] byteCodeCache; | ||
|
||
__gshared int byteCodeCacheTop = 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do hope these are private... Also they could just be an int[]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review round for bc_common.d
src/dmd/ctfe/bc_common.d
Outdated
} | ||
|
||
|
||
static assert(() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unittest
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unittests don't run at compile time ...
src/dmd/ctfe/bc_common.d
Outdated
{ | ||
BCTypeEnum commonType = commonTypeEnum(this.type.type, rhs.type.type); | ||
|
||
if (this.vType == rhs.vType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ((this.vType != rhs.vType) return false;
src/dmd/ctfe/bc_common.d
Outdated
} | ||
} | ||
|
||
pragma(msg, "Sizeof BCValue: ", BCValue.sizeof); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put this behind debug
conditional
src/dmd/ctfe/bc_common.d
Outdated
} | ||
|
||
pragma(msg, "Sizeof BCValue: ", BCValue.sizeof); | ||
__gshared static immutable bcLastCond = () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these do not need __gshared
and they feel like they should be (static immutable
) members of their types
src/dmd/ctfe/bc_common.d
Outdated
return result; | ||
}(); | ||
|
||
__gshared static immutable bcNull = () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
src/dmd/ctfe/bc_common.d
Outdated
__gshared static immutable bcFour = BCValue(Imm32(4)); | ||
__gshared static immutable bcOne = BCValue(Imm32(1)); | ||
__gshared static immutable bcZero = BCValue(Imm32(0)); | ||
__gshared static immutable i32Type = BCType(BCTypeEnum.i32); | ||
__gshared static immutable u32Type = BCType(BCTypeEnum.u32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
src/dmd/ctfe/bc_common.d
Outdated
|
||
BCTypeEnum commonTypeEnum(BCTypeEnum lhs, BCTypeEnum rhs) pure @safe | ||
{ | ||
// HACK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what hack?
src/dmd/ctfe/bc_common.d
Outdated
bool ifTrue; | ||
} | ||
|
||
const(uint) align4(const uint val) @safe pure @nogc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these first couple of functions feel like they should be part of root
or common
, the static
s should probably be private.
The whole fpconv module is probably going to be deleted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review round for bc_interpreter.
General comments: lots of std
usage for debug.
src/dmd/ctfe/bc_interpreter.d
Outdated
{ | ||
if (cRetval.vType == BCValueType.Exception) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert(cRetval.vType == BCValueType.Exception);
and remove the massive indentation
src/dmd/ctfe/bc_interpreter.d
Outdated
|
||
// we return to unroll | ||
// lets first handle the case in which there are catches on the catch stack | ||
if (catches.length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use early return here
src/dmd/ctfe/bc_interpreter.d
Outdated
|
||
bool Return() | ||
{ | ||
if (n_return_addrs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
src/dmd/ctfe/bc_interpreter.d
Outdated
break; | ||
case LongInst.ImmEq: | ||
{ | ||
if ((*lhsStackRef) == imm32c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cond = (*lhsStackRef) == imm32c);
, ditto for the cases that follow this
src/dmd/ctfe/bc_interpreter.d
Outdated
uint _lhs = *lhsRef & uint.max; | ||
float flhs = *cast(float*)&_lhs; | ||
uint _rhs = *rhs & uint.max; | ||
float frhs = *cast(float*)&_rhs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make this a templated local function, templated on (T=={float, double}
and make these cases shorter
src/dmd/ctfe/bc_interpreter.d
Outdated
if (Return()) return cRetval; | ||
} | ||
break; | ||
case LongInst.RetS64: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
src/dmd/ctfe/bc_interpreter.d
Outdated
{ | ||
if (*rhs == 0 && *lhsRef == 0) | ||
{ | ||
*lhsStackRef = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use an early break
src/dmd/ctfe/bc_interpreter.d
Outdated
const lhs_length = _lhs ? loadu32(llbasep) : 0; | ||
const rhs_length = _rhs ? loadu32(rlbasep) : 0; | ||
|
||
if (const newLength = lhs_length + rhs_length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
src/dmd/ctfe/bc_interpreter.d
Outdated
assert(_lhs && _rhs, "trying to deref nullPointers"); | ||
if (_lhs == _rhs) | ||
{ | ||
cond = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
early break
src/dmd/ctfe/bc_interpreter.d
Outdated
} | ||
} | ||
|
||
static assert(testFact().interpret([imm32(5)]) == imm32(120)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this fails with
src\dmd\ctfe\bc_interpreter.d(1697): Error: function `dmd.ctfe.bc_interpreter.interpret(ref BCGen gen, BCValue[] args, BCHeap* heapPtr = null)` is not callable using argument types `(BCGen, BCValue[])`
src\dmd\ctfe\bc_interpreter.d(1697): cannot pass rvalue argument `testFact()` of type `BCGen` to parameter `ref BCGen gen`
src\dmd\ctfe\bc_interpreter.d(1697): while evaluating: `static assert(interpret(testFact(), [imm32(5u, false)]) == imm32(120u, false))`
expressions fire for -v and compile time (-debug=bc) respectively.
This adds a preview flag but it shouldn't be merged just yet but you can play with it yourself.
I'll add a markdown file that explains the design in more depth at some point.