// If val is a constant and addr refers to a global variable which is defined in // this module or an element thereof, simulate the effect of storing val at addr // in the global variable's initializer and return true, otherwise return false. // Precondition: we are compiling the init function. func (fr *frame) maybeStoreInInitializer(val, addr llvm.Value) bool { if val.IsAConstant().IsNil() { return false } if !addr.IsAConstantExpr().IsNil() && addr.OperandsCount() >= 2 && // TODO(pcc): Explicitly check that this is a constant GEP. // I don't think there are any other kinds of constantexpr which // satisfy the conditions we test for here, so this is probably safe. !addr.Operand(0).IsAGlobalVariable().IsNil() && addr.Operand(1).IsNull() { gv := addr.Operand(0) globalInit, ok := fr.globalInits[gv] if !ok { return false } indices := make([]uint32, addr.OperandsCount()-2) for i := range indices { op := addr.Operand(i + 2) if op.IsAConstantInt().IsNil() { return false } indices[i] = uint32(op.ZExtValue()) } globalInit.update(gv.Type().ElementType(), indices, val) return true } else if !addr.IsAGlobalVariable().IsNil() { if globalInit, ok := fr.globalInits[addr]; ok { globalInit.update(addr.Type().ElementType(), nil, val) return true } return false } else { return false } }