Closed FreakyPenguin closed 10 years ago
This is a bug in my handling of forward references when lowering the pure AST to the C++ objects. The resolution may be a little tricky, because my choice to leave explicit (and usually redundant) type information out of symbol references leaves me in a bit of a bind. I've got to think for a bit to see if I can dig myself out of this problem without a radical change to the AST.
Nope. Bummer.
define void @foo() {
entry:
ret void
dead0: ; preds = %dead1
%x0 = add i32 %x1, %x1
br label %dead1
dead1: ; preds = %dead0
%x1 = add i32 %x0, %x0
br label %dead0
}
is legal, but in my AST too many types would be elided and the type of %x0 and %x1 wouldn't be determined - so I've got to add types to a lot of stuff. It'll fix the bug, but the consequences for downstream users won't be pretty. I don't seem to have much of a choice, though.
would one alternative fix be to have a "type unification" pass in the pure ast -> c++ direction? (note that i don't have any large code that'll be impacted by this, merely wondering outloud)
Can you explain what changes to the AST you have in mind? It sounds like you're saying that Name
s all need to have type annotations attached to them, but that doesn't make sense to me. I can't see why it would ever be necessary for the abstract syntax to contain a type annotation anywhere that the concrete syntax doesn't. If the AST needs to be elaborated with further type information prior to converting it to the c++ representation, that elaboration could go in a separate, user-hidden pass like cartazio suggested.
Nevermind, I see now. Those i32s annotating the add instructons in the concrete syntax don't show up anywhere in the abstract syntax, and without those the AST is genuinely ambiguous. Yes, that is awfully unfortunate.
After some examination, the annotations on all the instructions in the concrete syntax all seem to be small local inferences away from simply having a type on each reference to a variable (e.g. the add instruction only writes the operand type once, rather than once for each operand, because the two operands must have the same type).
The change/fix that is the best compromise I've found between consistency with the concrete syntax and general cleanliness and internal consistency is to add a type field to both the LocalReference constructor for Operand and the GlobalReference constructor for Constant.
This is now fixed, with associated necessary AST changes adding type annotations to symbol references, is in 3.3.12.0 and 3.4.3.0.
Hi, I ran into the following problem with version 3.4.2.2:
Basically I'm trying to get the pure AST from the impure representation, do some modifications and get it back into the internal representation. When trying to do this I noticed that there seems to be something wrong in either
moduleAST
orwithModuleFromAST
, even when I made no modifications to the AST the latter failed. But the bitcode itself (it's from clang), seems to be correct since executing it (using MCJIT) works just fine if I use the originial module that comes fromwithModuleFromBitcode
.I tried to reduce my example as much as possible, and added the Haskell source and the LLVM-source below. Any idea why this is happening or how to fix it? The error produced is
test-llvm: user error (reference to undefined local: Name "cache.07")
Haskell Source:
LLVM Source: (for Rx-linked-cg.bc)
Thanks, Antoine