[LLVMdev] gfortran: array constructor problems
Michael McCracken
michael.mccracken at gmail.com
Tue Sep 5 11:53:20 PDT 2006
Hi, in order to get a handle on the questions in Chris's previous
email, I rebuilt LLVM with debugging info, and then rebuilt gcc4 with
CHECKING_ENABLED.
In the process, I ran into an assertion error when compiling the first
part of libgfortran:
../../src/gcc/llvm-convert.cpp:3871: failed assertion
`(TREE_CONSTANT(exp) || TREE_CODE(exp) == STRING_CST) && "Isn't a
constant!"'
In this case, TreeConstantToLLVM::Convert() is getting a constant to
convert that fails the test "TREE_CONSTANT(exp)"
(from my gdb session:)
>Breakpoint 2, TreeConstantToLLVM::Convert (exp=0x45e48c60) at
../../src/gcc/llvm-convert.cpp:3868
>2: exp->common.constant_flag = 0
>1: exp->common.code = CONSTRUCTOR
>From the backtrace the problem, calls ConvertArrayCONSTRUCTOR:
(gdb) bt
#0 0x9004802c in kill ()
#1 0x9012dfb4 in abort ()
#2 0x94af90b0 in __eprintf ()
#3 0x0029450c in TreeConstantToLLVM::Convert (exp=0x0) at
../../src/gcc/llvm-convert.cpp:3870
#4 0x00295d80 in TreeConstantToLLVM::ConvertArrayCONSTRUCTOR
(exp=0x45e48d20) at ../../src/gcc/llvm-convert.cpp:4083
#5 0x0028b624 in emit_global_to_llvm (decl=0x45e4c700) at
../../src/gcc/llvm-backend.cpp:377
#6 0x00284844 in rest_of_decl_compilation (decl=0x45e4c700,
top_level=0, at_end=0) at ../../src/gcc/passes.c:252
#7 0x002a7da8 in TreeToLLVM::EmitBIND_EXPR (this=0xbfffe63c,
exp=0x45e4d5a0, DestLoc=0x0) at ../../src/gcc/llvm-convert.cpp:1119
#8 0x00297ac0 in TreeToLLVM::Emit (this=0xbfffe63c, exp=0x45e4d5a0,
DestLoc=0x0) at ../../src/gcc/llvm-convert.cpp:474
#9 0x002882f0 in llvm_emit_code_for_current_function
(fndecl=0x45e4ae00) at ../../src/gcc/llvm-backend.cpp:309
It is compiling libgfortran/intrinsics/selected_int_kind.f90, which
has only one array constructor, shown below. (this part is actually
generated at build time as selected_int_kind.inc)
type :: int_info
integer :: kind
integer :: range
end type int_info
integer, parameter :: c = 4
type (int_info), parameter :: int_infos(c) = (/ &
int_info (1, range(0_1)), &
int_info (2, range(0_2)), &
int_info (4, range(0_4)), &
int_info (8, range(0_8)) /)
This is trying to declare a constant array of int_info structures.
range() is an intrinsic function that returns the expoent range of the
argument's type kind. I haven't quite been able to figure out where
that gets evaluated, but I am pretty sure it should be a constant at
compile time.
Here's the output of debug_tree() for the expression that breaks the assertion:
Breakpoint 2, TreeConstantToLLVM::Convert (exp=0x45e48c60) at
../../src/gcc/llvm-convert.cpp:3868
2: exp->common.constant_flag = 0
1: debug_tree (exp) = <constructor 0x45e48c60
type <record_type 0x45e4c180 int_info BLK
size <integer_cst 0x45e23870 constant invariant 64>
unit size <integer_cst 0x45e238a0 constant invariant 8>
align 32 symtab 1183925312 alias set -1
fields <field_decl 0x45e4c200 kind type <integer_type 0x45e28480 int4>
asm-frame-size 0 SI file
/Users/mike/Documents/hpcl/LLVM/fortran/gcc4/src/libgfortran/intrinsics/selected_int_kind.f90
line 22
size <integer_cst 0x45e23600 constant invariant 32>
unit size <integer_cst 0x45e23120 constant invariant 4>
align 32 offset_align 128
offset <integer_cst 0x45e23150 constant invariant 0>
bit offset <integer_cst 0x45e23c60 constant invariant 0>
context <record_type 0x45e4c180 int_info> arguments <integer_cst
0x45e23150 0>
LLVM: uint 0 chain <field_decl 0x45e4c280 range>>
pointer_to_this <pointer_type 0x45e4c580> chain <type_decl
0x45e4c300 D.269>>
arg 0 <tree_list 0x45e49840 purpose <field_decl 0x45e4c200 kind>
value <integer_cst 0x45e23db0 constant invariant 1>
chain <tree_list 0x45e49860 purpose <field_decl 0x45e4c280
range> value <integer_cst 0x45e23db0 1>>>>
I'm having a hard time mapping this output to what I expected from the
structure, but that may be my inexperience with gcc internals.
For how to fix this, it seems like the problem here is in
gfc_conv_array_initializer() (trans-array.c:2905) , where
gfc_conv_structure() is called for EXPR_STRUCTURES in an array
initializer, even if it should be constant, and gfc_conv_structure()
doesn't set the constant_flag of the expression. My first guess is
that we might need to either relax the assertion (not sure what
problems that would cause), find a way to communicate that the
structure is intended to be contained in a constant array, or set the
structure as constant after we get it back in
gfc_conv_array_initializer()...
I'm not entirely sure how to proceed here, so any advice would be appreciated.
Thanks,
-mike
--
Michael McCracken
UCSD CSE PhD Candidate
research: http://www.cse.ucsd.edu/~mmccrack/
misc: http://michael-mccracken.net/wp/
More information about the llvm-dev
mailing list