Skip to content

Commit 427dde5

Browse files
authored
Merge pull request #1434 from PLC-lang/abroooo/fix_dbg_alignment
remove alignment for debug data
2 parents 7f35d82 + 25e79cc commit 427dde5

File tree

42 files changed

+863
-257
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+863
-257
lines changed

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
4343
!11 = !DIFile(filename: "file1.st", directory: "app")
4444
!12 = !DISubroutineType(flags: DIFlagPublic, types: !13)
4545
!13 = !{null}
46-
!14 = !DILocalVariable(name: "main", scope: !10, file: !11, line: 2, type: !15, align: 16)
46+
!14 = !DILocalVariable(name: "main", scope: !10, file: !11, line: 2, type: !15)
4747
!15 = !DIBasicType(name: "INT", size: 16, encoding: DW_ATE_signed, flags: DIFlagPublic)
4848
!16 = !DILocation(line: 2, column: 13, scope: !10)
4949
!17 = !DILocation(line: 10, column: 4, scope: !10)

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
4343
!11 = !DIFile(filename: "file1.st", directory: "")
4444
!12 = !DISubroutineType(flags: DIFlagPublic, types: !13)
4545
!13 = !{null}
46-
!14 = !DILocalVariable(name: "main", scope: !10, file: !11, line: 2, type: !15, align: 16)
46+
!14 = !DILocalVariable(name: "main", scope: !10, file: !11, line: 2, type: !15)
4747
!15 = !DIBasicType(name: "INT", size: 16, encoding: DW_ATE_signed, flags: DIFlagPublic)
4848
!16 = !DILocation(line: 2, column: 13, scope: !10)
4949
!17 = !DILocation(line: 10, column: 4, scope: !10)

src/codegen/debug.rs

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use inkwell::{
99
DWARFEmissionKind, DebugInfoBuilder,
1010
},
1111
module::Module,
12+
targets::TargetData,
1213
values::{BasicMetadataValueEnum, FunctionValue, GlobalValue, PointerValue},
1314
};
1415
use rustc_hash::FxHashMap;
@@ -18,13 +19,15 @@ use plc_diagnostics::diagnostics::Diagnostic;
1819
use plc_source::source_location::SourceLocation;
1920

2021
use crate::{
21-
datalayout::{Bytes, MemoryLocation},
2222
index::{Index, PouIndexEntry, VariableIndexEntry},
2323
typesystem::{DataType, DataTypeInformation, Dimension, StringEncoding, CHAR_TYPE, WCHAR_TYPE},
2424
DebugLevel, OptimizationLevel,
2525
};
2626

27-
use super::generators::{llvm::Llvm, statement_generator::FunctionContext, ADDRESS_SPACE_GLOBAL};
27+
use super::{
28+
generators::{llvm::Llvm, statement_generator::FunctionContext, ADDRESS_SPACE_GLOBAL},
29+
llvm_index::LlvmTypedIndex,
30+
};
2831

2932
#[derive(PartialEq, Eq)]
3033
#[allow(non_camel_case_types)]
@@ -83,6 +86,7 @@ pub trait Debug<'ink> {
8386
name: &str,
8487
datatype: &'idx DataType,
8588
index: &'idx Index,
89+
types_index: &'idx LlvmTypedIndex,
8690
) -> Result<(), Diagnostic>;
8791

8892
/// Creates a globally accessible variable with the given datatype.
@@ -167,6 +171,7 @@ pub struct DebugBuilder<'ink> {
167171
variables: FxHashMap<VariableKey, DILocalVariable<'ink>>,
168172
optimization: OptimizationLevel,
169173
files: FxHashMap<&'static str, DIFile<'ink>>,
174+
target_data: TargetData,
170175
}
171176

172177
/// A wrapper that redirects to correct debug builder implementation based on the debug context.
@@ -230,6 +235,9 @@ impl<'ink> DebugBuilderEnum<'ink> {
230235
"",
231236
);
232237

238+
let data_layout = module.get_data_layout();
239+
let data_layout = data_layout.as_str().to_str().expect("Data layout is valid");
240+
let target_data = TargetData::create(data_layout);
233241
let dbg_obj = DebugBuilder {
234242
context,
235243
debug_info,
@@ -238,6 +246,7 @@ impl<'ink> DebugBuilderEnum<'ink> {
238246
variables: Default::default(),
239247
optimization,
240248
files: Default::default(),
249+
target_data,
241250
};
242251
match debug_level {
243252
DebugLevel::VariablesOnly(_) => DebugBuilderEnum::VariablesOnly(dbg_obj),
@@ -273,8 +282,9 @@ impl<'ink> DebugBuilder<'ink> {
273282
&mut self,
274283
name: &str,
275284
members: &[VariableIndexEntry],
276-
index: &Index,
277285
location: &SourceLocation,
286+
index: &Index,
287+
types_index: &LlvmTypedIndex,
278288
) -> Result<(), Diagnostic> {
279289
//Create each type
280290
let index_types = members
@@ -285,22 +295,25 @@ impl<'ink> DebugBuilder<'ink> {
285295
index.get_type(type_name.as_ref()).map(|dt| (name, dt, location))
286296
})
287297
.collect::<Result<Vec<_>, Diagnostic>>()?;
298+
let struct_type = types_index.get_associated_type(name).map(|it| it.into_struct_type())?;
288299

289300
let file = location
290301
.get_file_name()
291302
.map(|it| self.get_or_create_debug_file(it))
292303
.unwrap_or_else(|| self.compile_unit.get_file());
293304

294305
let mut types = vec![];
295-
let mut running_offset = MemoryLocation::new(0);
296-
for (member_name, dt, location) in index_types.into_iter() {
297-
let di_type = self.get_or_create_debug_type(dt, index)?;
306+
for (element_index, (member_name, dt, location)) in index_types.into_iter().enumerate() {
307+
let di_type = self.get_or_create_debug_type(dt, index, types_index)?;
298308

299309
//Adjust the offset based on the field alignment
300-
let type_info = dt.get_type_information();
301-
let alignment = type_info.get_alignment(index);
302-
let size = type_info.get_size(index).unwrap();
303-
running_offset = running_offset.align_to(alignment);
310+
let size = types_index
311+
.find_associated_type(dt.get_name())
312+
.map(|llvm_type| self.target_data.get_bit_size(&llvm_type))
313+
.unwrap_or(0);
314+
//Offset in bits
315+
let offset =
316+
self.target_data.offset_of_element(&struct_type, element_index as u32).unwrap_or(0) * 8;
304317

305318
types.push(
306319
self.debug_info
@@ -309,27 +322,25 @@ impl<'ink> DebugBuilder<'ink> {
309322
member_name,
310323
file,
311324
location.get_line_plus_one() as u32,
312-
size.bits().into(),
313-
alignment.bits(),
314-
running_offset.bits().into(),
325+
size,
326+
0, // No set alignment
327+
offset,
315328
DIFlags::PUBLIC,
316329
di_type.into(),
317330
)
318331
.as_type(),
319332
);
320-
running_offset += size;
321333
}
322334

323-
let struct_dt = index.get_type_information_or_void(name);
324-
335+
let size = self.target_data.get_bit_size(&struct_type);
325336
//Create a struct type
326337
let struct_type = self.debug_info.create_struct_type(
327338
file.as_debug_info_scope(),
328339
name,
329340
file,
330341
location.get_line_plus_one() as u32,
331-
running_offset.bits().into(),
332-
struct_dt.get_alignment(index).bits(),
342+
size,
343+
0, // No set alignment
333344
DIFlags::PUBLIC,
334345
None,
335346
types.as_slice(),
@@ -347,9 +358,9 @@ impl<'ink> DebugBuilder<'ink> {
347358
name: &str,
348359
inner_type: &str,
349360
dimensions: &[Dimension],
350-
size: Bytes,
351-
alignment: Bytes,
361+
size: u64,
352362
index: &Index,
363+
types_index: &LlvmTypedIndex,
353364
) -> Result<(), Diagnostic> {
354365
//find the inner type debug info
355366
let inner_type = index.get_type(inner_type)?;
@@ -360,11 +371,11 @@ impl<'ink> DebugBuilder<'ink> {
360371
//Convert to normal range
361372
.collect::<Result<Vec<Range<i64>>, _>>()
362373
.map_err(|err| Diagnostic::codegen_error(err, SourceLocation::undefined()))?;
363-
let inner_type = self.get_or_create_debug_type(inner_type, index)?;
374+
let inner_type = self.get_or_create_debug_type(inner_type, index, types_index)?;
364375
let array_type = self.debug_info.create_array_type(
365376
inner_type.into(),
366-
size.bits().into(),
367-
alignment.bits(),
377+
size,
378+
0, //No set alignment
368379
subscript.as_slice(),
369380
);
370381
self.register_concrete_type(name, DebugType::Composite(array_type));
@@ -375,17 +386,17 @@ impl<'ink> DebugBuilder<'ink> {
375386
&mut self,
376387
name: &str,
377388
inner_type: &str,
378-
size: Bytes,
379-
alignment: Bytes,
389+
size: u64,
380390
index: &Index,
391+
types_index: &LlvmTypedIndex,
381392
) -> Result<(), Diagnostic> {
382393
let inner_type = index.get_type(inner_type)?;
383-
let inner_type = self.get_or_create_debug_type(inner_type, index)?;
394+
let inner_type = self.get_or_create_debug_type(inner_type, index, types_index)?;
384395
let pointer_type = self.debug_info.create_pointer_type(
385396
name,
386397
inner_type.into(),
387-
size.bits().into(),
388-
alignment.bits(),
398+
size,
399+
0, //No set alignment
389400
inkwell::AddressSpace::from(ADDRESS_SPACE_GLOBAL),
390401
);
391402
self.register_concrete_type(name, DebugType::Derived(pointer_type));
@@ -396,14 +407,15 @@ impl<'ink> DebugBuilder<'ink> {
396407
&mut self,
397408
dt: &DataType,
398409
index: &Index,
410+
types_index: &LlvmTypedIndex,
399411
) -> Result<DebugType<'ink>, Diagnostic> {
400412
//Try to find a type in the types
401-
let dt_name = dt.get_name().to_lowercase();
413+
let dt_name = dt.get_name();
402414
//Attempt to re-register the type, this will do nothing if the type exists.
403415
//TODO: This will crash on recursive datatypes
404-
self.register_debug_type(&dt_name, dt, index)?;
416+
self.register_debug_type(dt_name, dt, index, types_index)?;
405417
self.types
406-
.get(&dt_name)
418+
.get(&dt_name.to_lowercase())
407419
.ok_or_else(|| {
408420
Diagnostic::new(format!("Cannot find debug information for type {dt_name}"))
409421
.with_error_code("E076")
@@ -416,21 +428,21 @@ impl<'ink> DebugBuilder<'ink> {
416428
name: &str,
417429
length: i64,
418430
encoding: StringEncoding,
419-
size: Bytes,
420-
alignment: Bytes,
431+
size: u64,
421432
index: &Index,
433+
types_index: &LlvmTypedIndex,
422434
) -> Result<(), Diagnostic> {
423435
// Register a utf8 or 16 basic type
424436
let inner_type = match encoding {
425437
StringEncoding::Utf8 => index.get_effective_type_or_void_by_name(CHAR_TYPE),
426438
StringEncoding::Utf16 => index.get_effective_type_or_void_by_name(WCHAR_TYPE),
427439
};
428-
let inner_type = self.get_or_create_debug_type(inner_type, index)?;
440+
let inner_type = self.get_or_create_debug_type(inner_type, index, types_index)?;
429441
//Register an array
430442
let array_type = self.debug_info.create_array_type(
431443
inner_type.into(),
432-
size.bits().into(),
433-
alignment.bits(),
444+
size,
445+
0, //No set alignment
434446
#[allow(clippy::single_range_in_vec_init)]
435447
&[(0..length)],
436448
);
@@ -442,11 +454,12 @@ impl<'ink> DebugBuilder<'ink> {
442454
&mut self,
443455
name: &str,
444456
referenced_type: &str,
445-
index: &Index,
446457
location: &SourceLocation,
458+
index: &Index,
459+
types_index: &LlvmTypedIndex,
447460
) -> Result<(), Diagnostic> {
448461
let inner_dt = index.get_effective_type_by_name(referenced_type)?;
449-
let inner_type = self.get_or_create_debug_type(inner_dt, index)?;
462+
let inner_type = self.get_or_create_debug_type(inner_dt, index, types_index)?;
450463
let file = location
451464
.get_file_name()
452465
.map(|it| self.get_or_create_debug_file(it))
@@ -458,7 +471,7 @@ impl<'ink> DebugBuilder<'ink> {
458471
file,
459472
location.get_line_plus_one() as u32,
460473
file.as_debug_info_scope(),
461-
inner_dt.get_type_information().get_alignment(index).bits(),
474+
0, //No set alignment
462475
);
463476
self.register_concrete_type(name, DebugType::Derived(typedef));
464477

@@ -542,11 +555,7 @@ impl<'ink> DebugBuilder<'ink> {
542555
.iter()
543556
.filter(|it| it.is_local() || it.is_temp() || it.is_return())
544557
{
545-
let var_type = index
546-
.find_effective_type_by_name(variable.get_type_name())
547-
.expect("Type should exist at this stage");
548-
let alignment = var_type.get_type_information().get_alignment(index).bits();
549-
self.register_local_variable(variable, alignment, func);
558+
self.register_local_variable(variable, 0, func);
550559
}
551560

552561
let implementation = pou.find_implementation(index).expect("A POU will have an impl at this stage");
@@ -634,22 +643,25 @@ impl<'ink> Debug<'ink> for DebugBuilder<'ink> {
634643
name: &str,
635644
datatype: &'idx DataType,
636645
index: &'idx Index,
646+
types_index: &LlvmTypedIndex,
637647
) -> Result<(), Diagnostic> {
638648
//check if the type is currently registered
639649
if !self.types.contains_key(&name.to_lowercase()) {
640650
let type_info = datatype.get_type_information();
641-
let size = type_info.get_size(index).unwrap();
642-
let alignment = type_info.get_alignment(index);
651+
let size = types_index
652+
.find_associated_type(name)
653+
.map(|llvm_type| self.target_data.get_bit_size(&llvm_type))
654+
.unwrap_or(0);
643655
let location = &datatype.location;
644656
match type_info {
645657
DataTypeInformation::Struct { members, .. } => {
646-
self.create_struct_type(name, members.as_slice(), index, location)
658+
self.create_struct_type(name, members.as_slice(), location, index, types_index)
647659
}
648660
DataTypeInformation::Array { name, inner_type_name, dimensions, .. } => {
649-
self.create_array_type(name, inner_type_name, dimensions, size, alignment, index)
661+
self.create_array_type(name, inner_type_name, dimensions, size, index, types_index)
650662
}
651663
DataTypeInformation::Pointer { name, inner_type_name, .. } => {
652-
self.create_pointer_type(name, inner_type_name, size, alignment, index)
664+
self.create_pointer_type(name, inner_type_name, size, index, types_index)
653665
}
654666
DataTypeInformation::Integer { signed, size, .. } => {
655667
let encoding = if type_info.is_bool() {
@@ -671,11 +683,11 @@ impl<'ink> Debug<'ink> for DebugBuilder<'ink> {
671683
let length = string_size
672684
.as_int_value(index)
673685
.map_err(|err| Diagnostic::codegen_error(err, SourceLocation::undefined()))?;
674-
self.create_string_type(name, length, *encoding, size, alignment, index)
686+
self.create_string_type(name, length, *encoding, size, index, types_index)
675687
}
676688
DataTypeInformation::Alias { name, referenced_type }
677689
| DataTypeInformation::Enum { name, referenced_type, .. } => {
678-
self.create_typedef_type(name, referenced_type, index, location)
690+
self.create_typedef_type(name, referenced_type, location, index, types_index)
679691
}
680692
// Other types are just derived basic types
681693
_ => Ok(()),
@@ -905,10 +917,13 @@ impl<'ink> Debug<'ink> for DebugBuilderEnum<'ink> {
905917
name: &str,
906918
datatype: &'idx DataType,
907919
index: &'idx Index,
920+
types_index: &'idx LlvmTypedIndex,
908921
) -> Result<(), Diagnostic> {
909922
match self {
910923
Self::None => Ok(()),
911-
Self::VariablesOnly(obj) | Self::Full(obj) => obj.register_debug_type(name, datatype, index),
924+
Self::VariablesOnly(obj) | Self::Full(obj) => {
925+
obj.register_debug_type(name, datatype, index, types_index)
926+
}
912927
}
913928
}
914929

src/codegen/generators/data_type_generator.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ pub fn generate_data_types<'ink>(
117117
generator.expand_opaque_types(user_type)?;
118118
}
119119

120+
// Now generate debug information for all types
121+
generator.generate_debug_types()?;
122+
120123
let mut tries = 0;
121124
let mut errors = FxHashMap::default();
122125

@@ -198,7 +201,6 @@ impl<'ink> DataTypeGenerator<'ink, '_> {
198201
/// Generates only an opaque type for structs.
199202
/// Eagerly generates but does not associate nested array and referenced aliased types
200203
fn create_type(&mut self, name: &str, data_type: &DataType) -> Result<BasicTypeEnum<'ink>, Diagnostic> {
201-
self.debug.register_debug_type(name, data_type, self.index)?;
202204
let information = data_type.get_type_information();
203205
match information {
204206
DataTypeInformation::Struct { source, .. } => match source {
@@ -462,6 +464,30 @@ impl<'ink> DataTypeGenerator<'ink, '_> {
462464

463465
Ok(result)
464466
}
467+
468+
fn generate_debug_types(&mut self) -> Result<(), Diagnostic> {
469+
for data_type in self
470+
.index
471+
.get_types()
472+
.entries()
473+
.flat_map(|(_, data_type)| data_type.first())
474+
.filter(|data_type| !data_type.is_generic(self.index))
475+
{
476+
self.debug.register_debug_type(data_type.get_name(), data_type, self.index, &self.types_index)?;
477+
}
478+
for data_type in self
479+
.index
480+
.get_pou_types()
481+
.entries()
482+
.flat_map(|(_, data_type)| data_type.first())
483+
.filter(|data_type| !data_type.is_generic(self.index))
484+
.filter(|data_type| data_type.is_backed_by_struct())
485+
{
486+
self.debug.register_debug_type(data_type.get_name(), data_type, self.index, &self.types_index)?;
487+
}
488+
489+
Ok(())
490+
}
465491
}
466492

467493
pub fn get_default_for(basic_type: BasicTypeEnum) -> BasicValueEnum {

0 commit comments

Comments
 (0)