[LLVMdev] RefineAbstractType

David Greene dag at cray.com
Thu Nov 13 16:27:11 PST 2008


On Wednesday 12 November 2008 19:13, Chris Lattner wrote:

> You shouldn't be refining the pointer, you should use:
>
> t1->refineAbstractType(t2)

Ok, I tried this and I get further.  But the type system seems to have trouble
when refining multiple types and those types resolve to the same thing.
I turned on DEBUG_MERGE_TYPES to illustrate:

*** First function type ***

TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
Derived new type: i32 *
TypeMap<>::add table contents:
 1. 0x3a4e910 [1 x i64]
Derived new type: [1 x i64]
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4eb60 [1 x i64] *
Derived new type: [1 x i64] *
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4f140 i64 *
 3. 0x3a4eb60 [1 x i64] *
Derived new type: i64 *
Derived new type: opaque
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4f140 i64 *
 3. 0x3a4eb60 [1 x i64] *
 4. 0x3a8c310 opaque *
Derived new type: opaque *
TypeMap<>::add table contents:
 1. 0x3a8c450 i32 (opaque *)
Derived new type: i32 (opaque *)
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4f140 i64 *
 3. 0x3a4eb60 [1 x i64] *
 4. 0x3a8c680 i32 (opaque *) *
 5. 0x3a8c310 opaque *
Derived new type: i32 (opaque *) *

*** First refinement ***

REFINING abstract type [0x3afd350 opaque] to [0x3a8c450 i32 (opaque *)]!
 REFINING user 0[0x3a8c310] of abstract type [0x3afd350 opaque] to [0x3a8c450 
i32 (opaque *)]!
RefineAbstractType(0x3afd350[opaque], 0x3a8c450 [i32 (opaque *)])
  remAbstractTypeUser[0x3afd350, opaque][0] User = 0x3a8c310
REFINING abstract type [0x3a8c310 i32 (\2) *] to [0x3a8c680 i32 (\2 *) *]!
Derived new type: opaque
  remAbstractTypeUser[0x3a8c450, i32 (\2 *)][1] User = 0x3a8c310
 REFINING user 0[0x3a8c450] of abstract type [0x3a8c310 i32 (\2) *] to 
[0x3a8c680 i32 (\2 *) *]!
RefineAbstractType(0x3a8c310[i32 (\2) *], 0x3a8c680 [i32 (\2 *) *])
  remAbstractTypeUser[0x3a8c310, i32 (\2) *][0] User = 0x3a8c450
typeIsREFINED type: 0x3a8c680 i32 (\2) *
  remAbstractTypeUser[0x3a8c680, i32 (\2) *][0] User = 0x3a8c450
typeIsREFINED type: 0x3a8c450 i32 (i32 (\2) *)
  remAbstractTypeUser[0x3a8c450, i32 (i32 (\2) *)][0] User = 0x3a8c680
  remAbstractTypeUser[0x3a8c810, opaque][0] User = 0x3a8c310
TypeMap<>::add table contents:
 1. 0x3a8c310 void ()
 2. 0x3a8c450 i32 (i32 (\2) *)

*** Ok, this all looks perfect at this point ***

*** Second function type ***

Derived new type: void ()
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4f140 i64 *
 3. 0x3a4eb60 [1 x i64] *
 4. 0x3a8cb40 void () *
 5. 0x3a8c680 i32 (\2) *
Derived new type: void () *
Derived new type: opaque
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4f140 i64 *
 3. 0x3a4eb60 [1 x i64] *
 4. 0x3a8cb40 void () *
 5. 0x3a8c680 i32 (\2) *
 6. 0x3a8d000 opaque *
Derived new type: opaque *
TypeMap<>::add table contents:
 1. 0x3a8c310 void ()
 2. 0x3a8c450 i32 (i32 (\2) *)
 3. 0x3a8d1c0 i32 (opaque *)
Derived new type: i32 (opaque *)
TypeMap<>::add table contents:
 1. 0x3a4e6a0 i32 *
 2. 0x3a4f140 i64 *
 3. 0x3a4eb60 [1 x i64] *
 4. 0x3a8cb40 void () *
 5. 0x3a8c680 i32 (\2) *
 6. 0x3a8d420 i32 (opaque *) *
 7. 0x3a8d000 opaque *
Derived new type: i32 (opaque *) *

*** Second refinement -- note that it's the same as the first refinement,
even "opaque" has the same address!  That seems suspicious to me. ***

REFINING abstract type [0x3afd350 opaque] to [0x3a8d1c0 i32 (opaque *)]!
 REFINING user 0[0x3a8d000] of abstract type [0x3afd350 opaque] to [0x3a8d1c0 
i32 (opaque *)]!
RefineAbstractType(0x3afd350[opaque], 0x3a8d1c0 [i32 (opaque *)])
  remAbstractTypeUser[0x3afd350, opaque][0] User = 0x3a8d000
REFINING abstract type [0x3a8d000 i32 (\2) *] to [0x3a8c680 i32 (\2) *]!
  remAbstractTypeUser[0x3a8d1c0, i32 (\2 *)][1] User = 0x3a8d000
 REFINING user 0[0x3a8d1c0] of abstract type [0x3a8d000 i32 (\2) *] to 
[0x3a8c680 i32 (\2) *]!
RefineAbstractType(0x3a8d000[i32 (\2) *], 0x3a8c680 [i32 (\2) *])
  remAbstractTypeUser[0x3a8d000, i32 (\2) *][0] User = 0x3a8d1c0
REFINING abstract type [0x3a8d1c0 i32 (i32 (\2) *)] to [0x3a8c450 i32 (i32 
(\2) *)]!
 REFINING user 0[0x3a8d420] of abstract type [0x3a8d1c0 i32 (i32 (\2) *)] to 
[0x3a8c450 i32 (i32 (\2) *)]!
RefineAbstractType(0x3a8d1c0[i32 (i32 (\2) *)], 0x3a8c450 [i32 (i32 (\2) *)])
  remAbstractTypeUser[0x3a8d1c0, i32 (i32 (\2) *)][0] User = 0x3a8d420
REFINING abstract type [0x3a8d420 i32 (i32 (\2) *) *] to [0x3a8c680 i32 (\2) 
*]!
  remAbstractTypeUser[0x3a8c810, opaque][2] User = 0x3a8d420
  remAbstractTypeUser[0x3a8c810, opaque][0] User = 0x3a8d000

*** BLAMMO! ***

llvm/lib/VMCore/Type.cpp:474: llvm::FunctionType::FunctionType(const 
llvm::Type*, const std::vector<const llvm::Type*, std::allocator<const 
llvm::Type*> >&, bool): Assertion `(Params[i]->isFirstClassType() || 
isa<OpaqueType>(Params[i])) && "Function arguments must be value types!"' 
failed.
Caught signal 6

Any idea what's happening?

Is it just the case that I shouldn't be doing two refinements that yield the 
same type?  How do I know in general that that will happen?  Right now
I'm refining types at the earliest possible moment, as we go along
processing the code.  Is there a requirement to only refine after all types
have been created?  I can't wait until all of the code is seen in general
because we need to dump asm after processing each function -- we 
can't wait until we've seen all functions (=> we can't wait until we've
seen all types to refine).

                                                -Dave



More information about the llvm-dev mailing list