[cfe-dev] static const structures declared as "external global %struct.S" instead of "external constant %struct.S"

Robert Lytton robert at xmos.com
Fri Dec 6 08:35:44 PST 2013


Hi,

I have narrowed the issue down to CodeGenModule::GetOrCreateLLVMGlobal()
This I assume is due to the uncertainty of whether a ctor/dtor will need to run on the 'const' data.

During CodeGenModule::EmitGlobalVarDefinition() the code explicitly checks the ctor/dtor situation:
 // If it is safe to mark the global 'constant', do so now.
  GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
                  isTypeConstant(D->getType(), true));

However this is only done for definitions and not declarations.
Should declarations be handled in a similar way?

Dumping the state of the 'VarDecl *D' for the example in the previous emails gives:

GetOrCreateLLVMGlobal
VarDecl 0x333c230 <test.cpp:5:3, col:23> i 'const int [2]' static
const int identifier[2]
isTypeConstant true

GetOrCreateLLVMGlobal
VarDecl 0x337eed0 <test.cpp:13:3, col:25> j 'const struct S':'const struct S' static
const struct S identifier
isTypeConstant false

EmitGlobalVarDefinition
GetOrCreateLLVMGlobal
VarDecl 0x337f7f0 parent 0x337ece0 prev 0x337eed0 <test.cpp:17:1, col:27> j 'const struct S':'const struct S'
`-InitListExpr 0x337f920 <col:23, col:27> 'const struct S':'const struct S'
  |-IntegerLiteral 0x337f890 <col:24> 'int' 1
  `-IntegerLiteral 0x337f8b0 <col:26> 'int' 2
const struct S identifier
NeedsGlobalCtor false
NeedsGlobalDtor false
isTypeConstant true

GetOrCreateLLVMGlobal
VarDecl 0x337fb80 <test.cpp:21:3, col:25> k 'const struct S':'const struct S' static
const struct S identifier
isTypeConstant false


________________________________
From: Robert Lytton
Sent: 06 December 2013 14:41
To: cfe-dev at cs.uiuc.edu
Subject: static const structures declared as "external global %struct.S" instead of "external constant %struct.S"

Hi,

I have a problem relating to the way clang handles static const structure declarations in c++ classes.

If only the declaration is visible:
    class K {static const struct S k; ...}
the constness is not emitted in the declaration:
    @_ZN1K1kE = external global %struct.S
should this not be:
    @_ZN1K1kE = external constant %struct.S

If the definition is visible too:
    class J {static const struct S j;...}
    const struct S J::j = {1,2};
we get a global 'const' definition, viz:
    @_ZN1J1jE = constant %struct.S { i32 1, i32 2 }, align 4

It should be noted that the handling of arrays always uses const - see below.

Am I correct in believing this is a bug?
Can anyone direct me to where the problem may reside?

This is a problem on the XCore target as we handle constant and non-constant data in separate areas and hence will emit different assembler instructions.

Robert


struct S{int s1; int s2;};

class I {
  static const int i[2];
  static int ii();
};
int I::ii(){return i[0];}
// I::i defined else where - OK

class J {
  static const struct S j;
  static struct S jj();
};
struct S J::jj(){return j;}
const struct S J::j = {1,2};


class K {
  static const struct S k;
  static struct S kk();
};
struct S K::kk(){return k;}
// K::k defined else where - const is lost


%struct.S = type { i32, i32 }
@_ZN1I1iE = external constant [2 x i32]
@_ZN1J1jE = constant %struct.S { i32 1, i32 2 }, align 4
@_ZN1K1kE = external global %struct.S

define i32 @_ZN1I2iiEv() #0 align 2 {
entry:
  %0 = load i32* getelementptr inbounds ([2 x i32]* @_ZN1I1iE, i32 0, i32 0), align 4
  ret i32 %0
}

define void @_ZN1J2jjEv(%struct.S* noalias sret %agg.result) #0 align 2 {
entry:
  %0 = bitcast %struct.S* %agg.result to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast (%struct.S* @_ZN1J1jE to i8*), i32 8, i32 4, i1 false)
  ret void
}

define void @_ZN1K2kkEv(%struct.S* noalias sret %agg.result) #0 align 2 {
entry:
  %0 = bitcast %struct.S* %agg.result to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast (%struct.S* @_ZN1K1kE to i8*), i32 8, i32 4, i1 false)
  ret void
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131206/7dc30389/attachment.html>


More information about the cfe-dev mailing list