265 changes: 265 additions & 0 deletions lldb/test/Shell/SymbolFile/DWARF/x86/debug-names-signature.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
## Test that we can correctly complete types even if the debug_names index
## contains entries referring to declaration dies (clang emitted entries like
## that until bd5c6367bd7).
##
## This test consists of two compile units and one type unit. CU1 has the
## definition of a variable, but only a forward-declaration of its type. When
## attempting to find a definition, the debug_names lookup will return the DIE
## in CU0, which is also a forward-declaration (with a reference to a type
## unit). LLDB needs to find the definition of the type within the type unit.

# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
# RUN: %lldb %t -o "target variable s" -o exit | FileCheck %s

# CHECK: (lldb) target variable s
# CHECK-NEXT: (Struct) s = (member = 47)

.data
.p2align 2, 0x0
.long 0
s:
.long 47 # 0x2f

.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 65 # DW_TAG_type_unit
.byte 1 # DW_CHILDREN_yes
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 2 # Abbreviation Code
.byte 19 # DW_TAG_structure_type
.byte 1 # DW_CHILDREN_yes
.byte 54 # DW_AT_calling_convention
.byte 11 # DW_FORM_data1
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 3 # Abbreviation Code
.byte 13 # DW_TAG_member
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 56 # DW_AT_data_member_location
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 4 # Abbreviation Code
.byte 36 # DW_TAG_base_type
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 62 # DW_AT_encoding
.byte 11 # DW_FORM_data1
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 5 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.byte 8 # DW_FORM_string
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 6 # Abbreviation Code
.byte 52 # DW_TAG_variable
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 2 # DW_AT_location
.byte 24 # DW_FORM_exprloc
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 7 # Abbreviation Code
.byte 19 # DW_TAG_structure_type
.byte 0 # DW_CHILDREN_no
.byte 60 # DW_AT_declaration
.byte 25 # DW_FORM_flag_present
.byte 105 # DW_AT_signature
.byte 32 # DW_FORM_ref_sig8
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 8 # Abbreviation Code
.byte 19 # DW_TAG_structure_type
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 60 # DW_AT_declaration
.byte 25 # DW_FORM_flag_present
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)

.section .debug_info,"",@progbits
.Ltu_begin0:
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
.Ldebug_info_start0:
.short 5 # DWARF version number
.byte 2 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.quad 4878254330033667422 # Type Signature
.long .LStruct_def-.Ltu_begin0 # Type DIE Offset
.byte 1 # Abbrev [1] 0x18:0x20 DW_TAG_type_unit
.short 33 # DW_AT_language
.LStruct_def:
.byte 2 # Abbrev [2] 0x23:0x10 DW_TAG_structure_type
.byte 5 # DW_AT_calling_convention
.long .Linfo_string6 # DW_AT_name
.byte 4 # DW_AT_byte_size
.byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member
.long .Linfo_string4 # DW_AT_name
.long .Lint-.Ltu_begin0 # DW_AT_type
.byte 0 # DW_AT_data_member_location
.byte 0 # End Of Children Mark
.Lint:
.byte 4 # Abbrev [4] 0x33:0x4 DW_TAG_base_type
.long .Linfo_string5 # DW_AT_name
.byte 5 # DW_AT_encoding
.byte 4 # DW_AT_byte_size
.byte 0 # End Of Children Mark
.Ldebug_info_end0:

.Lcu_begin0:
.long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
.Ldebug_info_start1:
.short 5 # DWARF version number
.byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 5 # Abbrev [5] 0xc:0x27 DW_TAG_compile_unit
.asciz "Hand-written DWARF" # DW_AT_producer
.short 33 # DW_AT_language
.Ls:
.byte 6 # Abbrev [6] 0x1e:0xb DW_TAG_variable
.long .Linfo_string3 # DW_AT_name
.long .LStruct_decl2-.Lcu_begin0 # DW_AT_type
.byte 9 # DW_AT_location
.byte 3
.quad s
.LStruct_decl2:
.byte 8 # Abbrev [8] 0x29:0x9 DW_TAG_structure_type
.long .Linfo_string6 # DW_AT_name
# DW_AT_declaration
.byte 0 # End Of Children Mark
.Ldebug_info_end1:

.Lcu_begin1:
.long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit
.Ldebug_info_start2:
.short 5 # DWARF version number
.byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 5 # Abbrev [5] 0xc:0x27 DW_TAG_compile_unit
.asciz "Hand-written DWARF" # DW_AT_producer
.short 33 # DW_AT_language
.LStruct_decl:
.byte 7 # Abbrev [7] 0x29:0x9 DW_TAG_structure_type
# DW_AT_declaration
.quad 4878254330033667422 # DW_AT_signature
.byte 0 # End Of Children Mark
.Ldebug_info_end2:

.section .debug_str,"MS",@progbits,1
.Linfo_string3:
.asciz "s" # string offset=60
.Linfo_string4:
.asciz "member" # string offset=62
.Linfo_string5:
.asciz "int" # string offset=69
.Linfo_string6:
.asciz "Struct" # string offset=73

.section .debug_names,"",@progbits
.long .Lnames_end0-.Lnames_start0 # Header: unit length
.Lnames_start0:
.short 5 # Header: version
.short 0 # Header: padding
.long 2 # Header: compilation unit count
.long 1 # Header: local type unit count
.long 0 # Header: foreign type unit count
.long 0 # Header: bucket count
.long 3 # Header: name count
.long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
.long 8 # Header: augmentation string size
.ascii "LLVM0700" # Header: augmentation string
.long .Lcu_begin0 # Compilation unit 0
.long .Lcu_begin1 # Compilation unit 1
.long .Ltu_begin0 # Type unit 0
.long .Linfo_string6 # String in Bucket 0: Struct
.long .Linfo_string3 # String in Bucket 1: s
.long .Linfo_string5 # String in Bucket 2: int
.long .Lnames1-.Lnames_entries0 # Offset in Bucket 0
.long .Lnames2-.Lnames_entries0 # Offset in Bucket 1
.long .Lnames0-.Lnames_entries0 # Offset in Bucket 2
.Lnames_abbrev_start0:
.byte 1 # Abbrev code
.byte 19 # DW_TAG_structure_type
.byte 2 # DW_IDX_type_unit
.byte 11 # DW_FORM_data1
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 2 # Abbrev code
.byte 52 # DW_TAG_variable
.byte 1 # DW_IDX_compile_unit
.byte 11 # DW_FORM_data1
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 3 # Abbrev code
.byte 36 # DW_TAG_base_type
.byte 2 # DW_IDX_type_unit
.byte 11 # DW_FORM_data1
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 4 # Abbrev code
.byte 19 # DW_TAG_structure_type
.byte 1 # DW_IDX_compile_unit
.byte 11 # DW_FORM_data1
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 0 # End of abbrev list
.Lnames_abbrev_end0:
.Lnames_entries0:
.Lnames1:
.byte 4 # Abbreviation code
.byte 1 # DW_IDX_compile_unit
.long .LStruct_decl-.Lcu_begin1 # DW_IDX_die_offset
.byte 1 # Abbreviation code
.byte 0 # DW_IDX_type_unit
.long .LStruct_def-.Ltu_begin0 # DW_IDX_die_offset
.byte 0
# End of list: Struct
.Lnames2:
.byte 2 # Abbreviation code
.byte 0 # DW_IDX_compile_unit
.long .Ls-.Lcu_begin0 # DW_IDX_die_offset
.byte 0
# End of list: s
.Lnames0:
.byte 3 # Abbreviation code
.byte 0 # DW_IDX_type_unit
.long .Lint-.Ltu_begin0 # DW_IDX_die_offset
.byte 0
# End of list: int
.p2align 2, 0x0
.Lnames_end0:
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
## Check that lldb can locate a static constant variable when its declaration is
## referenced by a debug_names index. This is a non-conforming extension used by
## dsymutil.

# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
# RUN: %lldb %t -o "target variable Class::constant" \
# RUN: -o "expr -l c++ -- Class::constant" -o exit | FileCheck %s

# CHECK: (lldb) target variable Class::constant
# CHECK-NEXT: (const int) Class::constant = 47
# CHECK: (lldb) expr -l c++ -- Class::constant
# CHECK-NEXT: (const int) $0 = 47

.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.byte 8 # DW_FORM_string
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 3 # Abbreviation Code
.byte 2 # DW_TAG_class_type
.byte 1 # DW_CHILDREN_yes
.byte 54 # DW_AT_calling_convention
.byte 11 # DW_FORM_data1
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 4 # Abbreviation Code
.byte 52 # DW_TAG_variable
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 63 # DW_AT_external
.byte 25 # DW_FORM_flag_present
.byte 60 # DW_AT_declaration
.byte 25 # DW_FORM_flag_present
.byte 28 # DW_AT_const_value
.byte 13 # DW_FORM_sdata
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 5 # Abbreviation Code
.byte 38 # DW_TAG_const_type
.byte 0 # DW_CHILDREN_no
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 6 # Abbreviation Code
.byte 36 # DW_TAG_base_type
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 14 # DW_FORM_strp
.byte 62 # DW_AT_encoding
.byte 11 # DW_FORM_data1
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_info,"",@progbits
.Lcu_begin0:
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
.Ldebug_info_start0:
.short 5 # DWARF version number
.byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.byte 1 # Abbrev [1] 0xc:0x40 DW_TAG_compile_unit
.asciz "Hand-written DWARF" # DW_AT_producer
.short 33 # DW_AT_language
.LClass:
.byte 3 # Abbrev [3] 0x29:0x10 DW_TAG_class_type
.byte 5 # DW_AT_calling_convention
.long .Linfo_string4 # DW_AT_name
.byte 1 # DW_AT_byte_size
.Lvariable:
.byte 4 # Abbrev [4] 0x2f:0x9 DW_TAG_variable
.long .Linfo_string5 # DW_AT_name
.long .Lconst_int-.Lcu_begin0 # DW_AT_type
# DW_AT_external
# DW_AT_declaration
.byte 47 # DW_AT_const_value
.byte 0 # End Of Children Mark
.Lconst_int:
.byte 5 # Abbrev [5] 0x39:0x5 DW_TAG_const_type
.long .Lint-.Lcu_begin0 # DW_AT_type
.Lint:
.byte 6 # Abbrev [6] 0x3e:0x4 DW_TAG_base_type
.long .Linfo_string6 # DW_AT_name
.byte 5 # DW_AT_encoding
.byte 4 # DW_AT_byte_size
.byte 0 # End Of Children Mark
.Ldebug_info_end0:

.section .debug_str,"MS",@progbits,1
.Linfo_string4:
.asciz "Class"
.Linfo_string5:
.asciz "constant"
.Linfo_string6:
.asciz "int"

.section .debug_names,"",@progbits
.long .Lnames_end0-.Lnames_start0 # Header: unit length
.Lnames_start0:
.short 5 # Header: version
.short 0 # Header: padding
.long 1 # Header: compilation unit count
.long 0 # Header: local type unit count
.long 0 # Header: foreign type unit count
.long 0 # Header: bucket count
.long 3 # Header: name count
.long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
.long 8 # Header: augmentation string size
.ascii "LLVM0700" # Header: augmentation string
.long .Lcu_begin0 # Compilation unit 0
.long .Linfo_string4 # String: Class
.long .Linfo_string5 # String: constant
.long .Linfo_string6 # String: int
.long .Lnames0-.Lnames_entries0
.long .Lnames3-.Lnames_entries0
.long .Lnames1-.Lnames_entries0
.Lnames_abbrev_start0:
.byte 1 # Abbrev code
.byte 2 # DW_TAG_class_type
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 2 # Abbrev code
.byte 52 # DW_TAG_variable
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 3 # Abbrev code
.byte 36 # DW_TAG_base_type
.byte 3 # DW_IDX_die_offset
.byte 19 # DW_FORM_ref4
.byte 0 # End of abbrev
.byte 0 # End of abbrev
.byte 0 # End of abbrev list
.Lnames_abbrev_end0:
.Lnames_entries0:
.Lnames0:
.byte 1 # Abbreviation code
.long .LClass-.Lcu_begin0 # DW_IDX_die_offset
.byte 0 # DW_IDX_parent
# End of list: Class
.Lnames3:
.byte 2 # Abbreviation code
.long .Lvariable-.Lcu_begin0 # DW_IDX_die_offset
.byte 0 # DW_IDX_parent
# End of list: constant
.Lnames1:
.byte 3 # Abbreviation code
.long .Lint-.Lcu_begin0 # DW_IDX_die_offset
.byte 0 # DW_IDX_parent
# End of list: int
.Lnames_end0:
Original file line number Diff line number Diff line change
Expand Up @@ -1731,7 +1731,29 @@ TEST_F(Testx86AssemblyInspectionEngine, TestAddESP) {
EXPECT_EQ(4 - 16, row_sp->GetCFAValue().GetOffset());
}

// FIXME add test for lea_rsp_pattern_p
TEST_F(Testx86AssemblyInspectionEngine, TestLEA_RSP_Pattern) {
UnwindPlan::Row::RegisterLocation regloc;
UnwindPlan::RowSP row_sp;
AddressRange sample_range;
UnwindPlan unwind_plan(eRegisterKindLLDB);
std::unique_ptr<x86AssemblyInspectionEngine> engine = Getx86_64Inspector();

uint8_t data[] = {
0x8d, 0x64, 0x24, 0x10, // lea rsp, [rsp + 0x10]
0x90 // nop
};

sample_range = AddressRange(0x1000, sizeof(data));

EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
data, sizeof(data), sample_range, unwind_plan));

row_sp = unwind_plan.GetRowForFunctionOffset(0);
EXPECT_EQ(0ull, row_sp->GetOffset());
EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp);
EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset());
}

TEST_F(Testx86AssemblyInspectionEngine, TestPopRBX) {
UnwindPlan::Row::RegisterLocation regloc;
Expand Down
411 changes: 105 additions & 306 deletions llvm/docs/AMDGPUUsage.rst

Large diffs are not rendered by default.

113 changes: 53 additions & 60 deletions llvm/docs/AssignmentTracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The core idea is to track more information about source assignments in order
and preserve enough information to be able to defer decisions about whether to
use non-memory locations (register, constant) or memory locations until after
middle end optimisations have run. This is in opposition to using
`llvm.dbg.declare` and `llvm.dbg.value`, which is to make the decision for most
`#dbg_declare` and `#dbg_value`, which is to make the decision for most
variables early on, which can result in suboptimal variable locations that may
be either incorrect or incomplete.

Expand All @@ -26,19 +26,18 @@ except for development and testing.
**Enable in Clang**: `-Xclang -fexperimental-assignment-tracking`

That causes Clang to get LLVM to run the pass `declare-to-assign`. The pass
converts conventional debug intrinsics to assignment tracking metadata and sets
converts conventional debug records to assignment tracking metadata and sets
the module flag `debug-info-assignment-tracking` to the value `i1 true`. To
check whether assignment tracking is enabled for a module call
`isAssignmentTrackingEnabled(const Module &M)` (from `llvm/IR/DebugInfo.h`).

## Design and implementation

### Assignment markers: `llvm.dbg.assign`
### Assignment markers: `#dbg_assign`

`llvm.dbg.value`, a conventional debug intrinsic, marks out a position in the
`#dbg_value`, a conventional debug record, marks out a position in the
IR where a variable takes a particular value. Similarly, Assignment Tracking
marks out the position of assignments with a new intrinsic called
`llvm.dbg.assign`.
marks out the position of assignments with a record called `#dbg_assign`.

In order to know where in IR it is appropriate to use a memory location for a
variable, each assignment marker must in some way refer to the store, if any
Expand All @@ -48,43 +47,37 @@ important benefit of referring to the store is that we can then build a two-way
mapping of stores<->markers that can be used to find markers that need to be
updated when stores are modified.

An `llvm.dbg.assign` marker that is not linked to any instruction signals that
An `#dbg_assign` marker that is not linked to any instruction signals that
the store that performed the assignment has been optimised out, and therefore
the memory location will not be valid for at least some part of the program.

Here's the `llvm.dbg.assign` signature. Each parameter is wrapped in
`MetadataAsValue`, and `Value *` type parameters are first wrapped in
`ValueAsMetadata`:
Here's the `#dbg_assign` signature. `Value *` type parameters are first wrapped
in `ValueAsMetadata`:

```
void @llvm.dbg.assign(Value *Value,
DIExpression *ValueExpression,
DILocalVariable *Variable,
DIAssignID *ID,
Value *Address,
DIExpression *AddressExpression)
#dbg_assign(Value *Value,
DIExpression *ValueExpression,
DILocalVariable *Variable,
DIAssignID *ID,
Value *Address,
DIExpression *AddressExpression)
```

The first three parameters look and behave like an `llvm.dbg.value`. `ID` is a
The first three parameters look and behave like an `#dbg_value`. `ID` is a
reference to a store (see next section). `Address` is the destination address
of the store and it is modified by `AddressExpression`. An empty/undef/poison
address means the address component has been killed (the memory address is no
longer a valid location). LLVM currently encodes variable fragment information
in `DIExpression`s, so as an implementation quirk the `FragmentInfo` for
`Variable` is contained within `ValueExpression` only.

The formal LLVM-IR signature is:
```
void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
```

### Instruction link: `DIAssignID`

`DIAssignID` metadata is the mechanism that is currently used to encode the
store<->marker link. The metadata node has no operands and all instances are
`distinct`; equality is checked for by comparing addresses.

`llvm.dbg.assign` intrinsics use a `DIAssignID` metadata node instance as an
`#dbg_assign` records use a `DIAssignID` metadata node instance as an
operand. This way it refers to any store-like instruction that has the same
`DIAssignID` attachment. E.g. For this test.cpp,

Expand All @@ -102,9 +95,9 @@ we get:
define dso_local noundef i32 @_Z3funi(i32 noundef %a) #0 !dbg !8 {
entry:
%a.addr = alloca i32, align 4, !DIAssignID !13
call void @llvm.dbg.assign(metadata i1 undef, metadata !14, metadata !DIExpression(), metadata !13, metadata i32* %a.addr, metadata !DIExpression()), !dbg !15
#dbg_assign(i1 undef, !14, !DIExpression(), !13, i32* %a.addr, !DIExpression(), !15)
store i32 %a, i32* %a.addr, align 4, !DIAssignID !16
call void @llvm.dbg.assign(metadata i32 %a, metadata !14, metadata !DIExpression(), metadata !16, metadata i32* %a.addr, metadata !DIExpression()), !dbg !15
#dbg_assign(i32 %a, !14, !DIExpression(), !16, i32* %a.addr, !DIExpression(), !15)
%0 = load i32, i32* %a.addr, align 4, !dbg !17
ret i32 %0, !dbg !18
}
Expand All @@ -116,16 +109,16 @@ entry:
!16 = distinct !DIAssignID()
```

The first `llvm.dbg.assign` refers to the `alloca` through `!DIAssignID !13`,
The first `#dbg_assign` refers to the `alloca` through `!DIAssignID !13`,
and the second refers to the `store` through `!DIAssignID !16`.

### Store-like instructions

In the absence of a linked `llvm.dbg.assign`, a store to an address that is
In the absence of a linked `#dbg_assign`, a store to an address that is
known to be the backing storage for a variable is considered to represent an
assignment to that variable.

This gives us a safe fall-back in cases where `llvm.dbg.assign` intrinsics have
This gives us a safe fall-back in cases where `#dbg_assign` records have
been deleted, the `DIAssignID` attachment on the store has been dropped, or the
optimiser has made a once-indirect store (not tracked with Assignment Tracking)
direct.
Expand All @@ -139,61 +132,61 @@ direct.
instruction. In this case, the assignment is considered to take place in
multiple positions in the program.

**Moving** a non-debug instruction: nothing new to do. Instructions linked to an
`llvm.dbg.assign` have their initial IR position marked by the position of the
`llvm.dbg.assign`.
**Moving** a non-debug instruction: nothing new to do. Instructions linked to a
`#dbg_assign` have their initial IR position marked by the position of the
`#dbg_assign`.

**Deleting** a non-debug instruction: nothing new to do. Simple DSE does not
require any change; it’s safe to delete an instruction with a `DIAssignID`
attachment. An `llvm.dbg.assign` that uses a `DIAssignID` that is not attached
attachment. A `#dbg_assign` that uses a `DIAssignID` that is not attached
to any instruction indicates that the memory location isn’t valid.

**Merging** stores: In many cases no change is required as `DIAssignID`
attachments are automatically merged if `combineMetadata` is called. One way or
another, the `DIAssignID` attachments must be merged such that new store
becomes linked to all the `llvm.dbg.assign` intrinsics that the merged stores
becomes linked to all the `#dbg_assign` records that the merged stores
were linked to. This can be achieved simply by calling a helper function
`Instruction::mergeDIAssignID`.

**Inlining** stores: As stores are inlined we generate `llvm.dbg.assign`
intrinsics and `DIAssignID` attachments as if the stores represent source
**Inlining** stores: As stores are inlined we generate `#dbg_assign`
records and `DIAssignID` attachments as if the stores represent source
assignments, just like the in frontend. This isn’t perfect, as stores may have
been moved, modified or deleted before inlining, but it does at least keep the
information about the variable correct within the non-inlined scope.

**Splitting** stores: SROA and passes that split stores treat `llvm.dbg.assign`
intrinsics similarly to `llvm.dbg.declare` intrinsics. Clone the
`llvm.dbg.assign` intrinsics linked to the store, update the FragmentInfo in
the `ValueExpression`, and give the split stores (and cloned intrinsics) new
**Splitting** stores: SROA and passes that split stores treat `#dbg_assign`
records similarly to `#dbg_declare` records. Clone the
`#dbg_assign` records linked to the store, update the FragmentInfo in
the `ValueExpression`, and give the split stores (and cloned records) new
`DIAssignID` attachments each. In other words, treat the split stores as
separate assignments. For partial DSE (e.g. shortening a memset), we do the
same except that `llvm.dbg.assign` for the dead fragment gets an `Undef`
same except that `#dbg_assign` for the dead fragment gets an `Undef`
`Address`.

**Promoting** allocas and store/loads: `llvm.dbg.assign` intrinsics implicitly
**Promoting** allocas and store/loads: `#dbg_assign` records implicitly
describe joined values in memory locations at CFG joins, but this is not
necessarily the case after promoting (or partially promoting) the
variable. Passes that promote variables are responsible for inserting
`llvm.dbg.assign` intrinsics after the resultant PHIs generated during
promotion. `mem2reg` already has to do this (with `llvm.dbg.value`) for
`llvm.dbg.declare`s. Where a store has no linked intrinsic, the store is
`#dbg_assign` records after the resultant PHIs generated during
promotion. `mem2reg` already has to do this (with `#dbg_value`) for
`#dbg_declare`s. Where a store has no linked record, the store is
assumed to represent an assignment for variables stored at the destination
address.

#### Debug intrinsic updates
#### Debug record updates

**Moving** a debug intrinsic: avoid moving `llvm.dbg.assign` intrinsics where
**Moving** a debug record: avoid moving `#dbg_assign` records where
possible, as they represent a source-level assignment, whose position in the
program should not be affected by optimization passes.

**Deleting** a debug intrinsic: Nothing new to do. Just like for conventional
debug intrinsics, unless it is unreachable, it’s almost always incorrect to
delete a `llvm.dbg.assign` intrinsic.
**Deleting** a debug record: Nothing new to do. Just like for conventional
debug records, unless it is unreachable, it’s almost always incorrect to
delete a `#dbg_assign` record.

### Lowering `llvm.dbg.assign` to MIR
### Lowering `#dbg_assign` to MIR

To begin with only SelectionDAG ISel will be supported. `llvm.dbg.assign`
intrinsics are lowered to MIR `DBG_INSTR_REF` instructions. Before this happens
To begin with only SelectionDAG ISel will be supported. `#dbg_assign`
records are lowered to MIR `DBG_INSTR_REF` instructions. Before this happens
we need to decide where it is appropriate to use memory locations and where we
must use a non-memory location (or no location) for each variable. In order to
make those decisions we run a standard fixed-point dataflow analysis that makes
Expand All @@ -214,9 +207,9 @@ to tackle:
clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp for examples.

* `trackAssignments` doesn't yet work for variables that have their
`llvm.dbg.declare` location modified by a `DIExpression`, e.g. when the
`#dbg_declare` location modified by a `DIExpression`, e.g. when the
address of the variable is itself stored in an `alloca` with the
`llvm.dbg.declare` using `DIExpression(DW_OP_deref)`. See `indirectReturn` in
`#dbg_declare` using `DIExpression(DW_OP_deref)`. See `indirectReturn` in
llvm/test/DebugInfo/Generic/assignment-tracking/track-assignments.ll and in
clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp for an
example.
Expand All @@ -225,13 +218,13 @@ to tackle:
memory location is available without using a `DIAssignID`. This is because
the storage address is not computed by an instruction (it's an argument
value) and therefore we have nowhere to put the metadata attachment. To solve
this we probably need another marker intrinsic to denote "the variable's
stack home is X address" - similar to `llvm.dbg.declare` except that it needs
to compose with `llvm.dbg.assign` intrinsics such that the stack home address
is only selected as a location for the variable when the `llvm.dbg.assign`
intrinsics agree it should be.
this we probably need another marker record to denote "the variable's
stack home is X address" - similar to `#dbg_declare` except that it needs
to compose with `#dbg_assign` records such that the stack home address
is only selected as a location for the variable when the `#dbg_assign`
records agree it should be.

* Given the above (a special "the stack home is X" intrinsic), and the fact
* Given the above (a special "the stack home is X" record), and the fact
that we can only track assignments with fixed offsets and sizes, I think we
can probably get rid of the address and address-expression part, since it
will always be computable with the info we have.
7 changes: 0 additions & 7 deletions llvm/docs/BranchWeightMetadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@ Supported Instructions

Metadata is only assigned to the conditional branches. There are two extra
operands for the true and the false branch.
We optionally track if the metadata was added by ``__builtin_expect`` or
``__builtin_expect_with_probability`` with an optional field ``!"expected"``.

.. code-block:: none
!0 = !{
!"branch_weights",
[ !"expected", ]
i32 <TRUE_BRANCH_WEIGHT>,
i32 <FALSE_BRANCH_WEIGHT>
}
Expand All @@ -50,7 +47,6 @@ is always case #0).
!0 = !{
!"branch_weights",
[ !"expected", ]
i32 <DEFAULT_BRANCH_WEIGHT>
[ , i32 <CASE_BRANCH_WEIGHT> ... ]
}
Expand All @@ -64,7 +60,6 @@ Branch weights are assigned to every destination.
!0 = !{
!"branch_weights",
[ !"expected", ]
i32 <LABEL_BRANCH_WEIGHT>
[ , i32 <LABEL_BRANCH_WEIGHT> ... ]
}
Expand All @@ -80,7 +75,6 @@ block and entry counts which may not be accurate with sampling.
!0 = !{
!"branch_weights",
[ !"expected", ]
i32 <CALL_BRANCH_WEIGHT>
}
Expand All @@ -101,7 +95,6 @@ is used.
!0 = !{
!"branch_weights",
[ !"expected", ]
i32 <INVOKE_NORMAL_WEIGHT>
[ , i32 <INVOKE_UNWIND_WEIGHT> ]
}
Expand Down
16 changes: 8 additions & 8 deletions llvm/docs/HowToUpdateDebugInfo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Deleting an IR-level Instruction

When an ``Instruction`` is deleted, its debug uses change to ``undef``. This is
a loss of debug info: the value of one or more source variables becomes
unavailable, starting with the ``llvm.dbg.value(undef, ...)``. When there is no
unavailable, starting with the ``#dbg_value(undef, ...)``. When there is no
way to reconstitute the value of the lost instruction, this is the best
possible outcome. However, it's often possible to do better:

Expand All @@ -172,7 +172,7 @@ possible outcome. However, it's often possible to do better:
define i16 @foo(i16 %a) {
%b = sext i16 %a to i32
%c = and i32 %b, 15
call void @llvm.dbg.value(metadata i32 %c, ...)
#dbg_value(i32 %c, ...)
%d = trunc i32 %c to i16
ret i16 %d
}
Expand All @@ -183,7 +183,7 @@ replaced with a simplified instruction:
.. code-block:: llvm
define i16 @foo(i16 %a) {
call void @llvm.dbg.value(metadata i32 undef, ...)
#dbg_value(i32 undef, ...)
%simplified = and i16 %a, 15
ret i16 %simplified
}
Expand All @@ -204,7 +204,7 @@ This results in better debug info because the debug use of ``%c`` is preserved:
define i16 @foo(i16 %a) {
%simplified = and i16 %a, 15
call void @llvm.dbg.value(metadata i16 %simplified, ...)
#dbg_value(i16 %simplified, ...)
ret i16 %simplified
}
Expand Down Expand Up @@ -249,7 +249,7 @@ module, and the second checks that this DI is still available after an
optimization has occurred, reporting any errors/warnings while doing so.

The instructions are assigned sequentially increasing line locations, and are
immediately used by debug value intrinsics everywhere possible.
immediately used by debug value records everywhere possible.

For example, here is a module before:

Expand All @@ -271,10 +271,10 @@ and after running ``opt -debugify``:
define void @f(i32* %x) !dbg !6 {
entry:
%x.addr = alloca i32*, align 8, !dbg !12
call void @llvm.dbg.value(metadata i32** %x.addr, metadata !9, metadata !DIExpression()), !dbg !12
#dbg_value(i32** %x.addr, !9, !DIExpression(), !12)
store i32* %x, i32** %x.addr, align 8, !dbg !13
%0 = load i32*, i32** %x.addr, align 8, !dbg !14
call void @llvm.dbg.value(metadata i32* %0, metadata !11, metadata !DIExpression()), !dbg !14
#dbg_value(i32* %0, !11, !DIExpression(), !14)
store i32 10, i32* %0, align 4, !dbg !15
ret void, !dbg !16
}
Expand Down Expand Up @@ -409,7 +409,7 @@ as follows:
$ clang -Xclang -fverify-debuginfo-preserve -Xclang -fverify-debuginfo-preserve-export=sample.json -g -O2 sample.c
Please do note that there are some known false positives, for source locations
and debug intrinsic checking, so that will be addressed as a future work.
and debug record checking, so that will be addressed as a future work.

Mutation testing for MIR-level transformations
----------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion llvm/docs/InstrRefDebugInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ referring to instruction values:

```llvm
%2 = add i32 %0, %1
call void @llvm.dbg.value(metadata i32 %2,
#dbg_value(metadata i32 %2,
```

In LLVM IR, the IR Value is synonymous with the instruction that computes the
Expand Down
83 changes: 44 additions & 39 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6288,11 +6288,11 @@ DIExpression
""""""""""""

``DIExpression`` nodes represent expressions that are inspired by the DWARF
expression language. They are used in :ref:`debug intrinsics<dbg_intrinsics>`
(such as ``llvm.dbg.declare`` and ``llvm.dbg.value``) to describe how the
expression language. They are used in :ref:`debug records <debugrecords>`
(such as ``#dbg_declare`` and ``#dbg_value``) to describe how the
referenced LLVM variable relates to the source language variable. Debug
intrinsics are interpreted left-to-right: start by pushing the value/address
operand of the intrinsic onto a stack, then repeatedly push and evaluate
expressions are interpreted left-to-right: start by pushing the value/address
operand of the record onto a stack, then repeatedly push and evaluate
opcodes from the DIExpression until the final variable description is produced.

The current supported opcode vocabulary is limited:
Expand Down Expand Up @@ -6389,23 +6389,24 @@ The current supported opcode vocabulary is limited:

IR for "*ptr = 4;"
--------------
call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !20)
#dbg_value(i32 4, !17, !DIExpression(DW_OP_LLVM_implicit_pointer), !20)
!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!20 = !DIExpression(DW_OP_LLVM_implicit_pointer))
!20 = !DILocation(line: 10, scope: !12)

IR for "**ptr = 4;"
--------------
call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !21)
#dbg_value(i32 4, !17,
!DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_implicit_pointer),
!21)
!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64)
!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!21 = !DIExpression(DW_OP_LLVM_implicit_pointer,
DW_OP_LLVM_implicit_pointer))
!21 = !DILocation(line: 10, scope: !12)

DWARF specifies three kinds of simple location descriptions: Register, memory,
and implicit location descriptions. Note that a location description is
Expand All @@ -6416,45 +6417,48 @@ sense that a debugger might modify its value), whereas *implicit locations*
describe merely the actual *value* of a source variable which might not exist
in registers or in memory (see ``DW_OP_stack_value``).

A ``llvm.dbg.declare`` intrinsic describes an indirect value (the address) of a
source variable. The first operand of the intrinsic must be an address of some
kind. A DIExpression attached to the intrinsic refines this address to produce a
A ``#dbg_declare`` record describes an indirect value (the address) of a
source variable. The first operand of the record must be an address of some
kind. A DIExpression operand to the record refines this address to produce a
concrete location for the source variable.

A ``llvm.dbg.value`` intrinsic describes the direct value of a source variable.
The first operand of the intrinsic may be a direct or indirect value. A
DIExpression attached to the intrinsic refines the first operand to produce a
A ``#dbg_value`` record describes the direct value of a source variable.
The first operand of the record may be a direct or indirect value. A
DIExpression operand to the record refines the first operand to produce a
direct value. For example, if the first operand is an indirect value, it may be
necessary to insert ``DW_OP_deref`` into the DIExpression in order to produce a
valid debug intrinsic.
valid debug record.

.. note::

A DIExpression is interpreted in the same way regardless of which kind of
debug intrinsic it's attached to.
debug record it's attached to.

DIExpressions are always printed and parsed inline; they can never be
referenced by an ID (e.g. ``!1``).

.. code-block:: text

!0 = !DIExpression(DW_OP_deref)
!1 = !DIExpression(DW_OP_plus_uconst, 3)
!1 = !DIExpression(DW_OP_constu, 3, DW_OP_plus)
!2 = !DIExpression(DW_OP_bit_piece, 3, 7)
!3 = !DIExpression(DW_OP_deref, DW_OP_constu, 3, DW_OP_plus, DW_OP_LLVM_fragment, 3, 7)
!4 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
!5 = !DIExpression(DW_OP_constu, 42, DW_OP_stack_value)
!DIExpression(DW_OP_deref)
!DIExpression(DW_OP_plus_uconst, 3)
!DIExpression(DW_OP_constu, 3, DW_OP_plus)
!DIExpression(DW_OP_bit_piece, 3, 7)
!DIExpression(DW_OP_deref, DW_OP_constu, 3, DW_OP_plus, DW_OP_LLVM_fragment, 3, 7)
!DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
!DIExpression(DW_OP_constu, 42, DW_OP_stack_value)

DIAssignID
""""""""""

``DIAssignID`` nodes have no operands and are always distinct. They are used to
link together `@llvm.dbg.assign` intrinsics (:ref:`debug
intrinsics<dbg_intrinsics>`) and instructions that store in IR. See `Debug Info
Assignment Tracking <AssignmentTracking.html>`_ for more info.
link together (:ref:`#dbg_assign records <debugrecords>`) and instructions
that store in IR. See `Debug Info Assignment Tracking
<AssignmentTracking.html>`_ for more info.

.. code-block:: llvm

store i32 %a, ptr %a.addr, align 4, !DIAssignID !2
llvm.dbg.assign(metadata %a, metadata !1, metadata !DIExpression(), !2, metadata %a.addr, metadata !DIExpression()), !dbg !3
#dbg_assign(%a, !1, !DIExpression(), !2, %a.addr, !DIExpression(), !3)

!2 = distinct !DIAssignID()

Expand All @@ -6468,17 +6472,18 @@ DIArgList
also be updated to mirror whatever we decide here.

``DIArgList`` nodes hold a list of constant or SSA value references. These are
used in :ref:`debug intrinsics<dbg_intrinsics>` (currently only in
``llvm.dbg.value``) in combination with a ``DIExpression`` that uses the
used in :ref:`debug records <debugrecords>` in combination with a
``DIExpression`` that uses the
``DW_OP_LLVM_arg`` operator. Because a DIArgList may refer to local values
within a function, it must only be used as a function argument, must always be
inlined, and cannot appear in named metadata.

.. code-block:: text

llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %b),
metadata !16,
metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus))
#dbg_value(!DIArgList(i32 %a, i32 %b),
!16,
!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus),
!26)

DIFlags
"""""""
Expand Down Expand Up @@ -12957,12 +12962,12 @@ an extra level of indentation. As an example:
#dbg_value(%inst1, !10, !DIExpression(), !11)
%inst2 = op2 %inst1, %c

These debug records are an optional replacement for
:ref:`debug intrinsics<dbg_intrinsics>`. Debug records will be output if the
``--write-experimental-debuginfo`` flag is passed to LLVM; it is an error for both
records and intrinsics to appear in the same module. More information about
debug records can be found in the `LLVM Source Level Debugging
<SourceLevelDebugging.html#format-common-intrinsics>`_ document.
These debug records replace the prior :ref:`debug intrinsics<dbg_intrinsics>`.
Debug records will be disabled if ``--write-experimental-debuginfo=false`` is
passed to LLVM; it is an error for both records and intrinsics to appear in the
same module. More information about debug records can be found in the `LLVM
Source Level Debugging <SourceLevelDebugging.html#format-common-intrinsics>`_
document.

.. _intrinsics:

Expand Down
8 changes: 4 additions & 4 deletions llvm/docs/MIRLangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -883,16 +883,16 @@ Where:

- ``debug-info-location`` identifies a DILocation metadata node.

These metadata attributes correspond to the operands of a ``llvm.dbg.declare``
IR intrinsic, see the :ref:`source level debugging<format_common_intrinsics>`
documentation.
These metadata attributes correspond to the operands of a ``#dbg_declare``
IR debug record, see the :ref:`source level
debugging<debug_records>` documentation.

Varying variable locations
^^^^^^^^^^^^^^^^^^^^^^^^^^

Variables that are not always on the stack or change location are specified
with the ``DBG_VALUE`` meta machine instruction. It is synonymous with the
``llvm.dbg.value`` IR intrinsic, and is written:
``#dbg_value`` IR record, and is written:

.. code-block:: text
Expand Down
5 changes: 3 additions & 2 deletions llvm/docs/Passes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -935,8 +935,9 @@ declarations and removes them. Dead declarations are declarations of functions
for which no implementation is available (i.e., declarations for unused library
functions).

``strip-debug-declare``: Strip all ``llvm.dbg.declare`` intrinsics
------------------------------------------------------------------
``strip-debug-declare``: Strip all ``llvm.dbg.declare`` intrinsics and
``#dbg_declare`` records.
-------------------------------------------------------------------

Performs code stripping. Similar to strip, but only strips
``llvm.dbg.declare`` intrinsics.
Expand Down
1 change: 1 addition & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ on support follow.
Extension Status
================ =================================================================
``A`` Supported
``B`` Supported
``C`` Supported
``D`` Supported
``F`` Supported
Expand Down
12 changes: 5 additions & 7 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ Changes to the LLVM IR

* ``icmp``
* ``fcmp``
* LLVM has switched from using debug intrinsics in textual IR to using debug
records by default. Details of the change and instructions on how to update
any downstream tools and tests can be found in the `migration docs
<https://llvm.org/docs/RemoveDIsDebugInfo.html>`_.

Changes to LLVM infrastructure
------------------------------
Expand Down Expand Up @@ -152,6 +156,7 @@ Changes to the RISC-V Backend
* Zaamo and Zalrsc are no longer experimental.
* Processors that enable post reg-alloc scheduling (PostMachineScheduler) by default should use the `UsePostRAScheduler` subtarget feature. Setting `PostRAScheduler = 1` in the scheduler model will have no effect on the enabling of the PostMachineScheduler.
* Zabha is no longer experimental.
* B (the collection of the Zba, Zbb, Zbs extensions) is supported.

Changes to the WebAssembly Backend
----------------------------------
Expand Down Expand Up @@ -225,13 +230,6 @@ Changes to the Metadata Info
Changes to the Debug Info
---------------------------------

* LLVM has switched from using debug intrinsics internally to using debug
records by default. This should happen transparently when using the DIBuilder
to construct debug variable information, but will require changes for any code
that interacts with debug intrinsics directly. Debug intrinsics will only be
supported on a best-effort basis from here onwards; for more information, see
the `migration docs <https://llvm.org/docs/RemoveDIsDebugInfo.html>`_.

Changes to the LLVM tools
---------------------------------
* llvm-nm and llvm-objdump can now print symbol information from linked
Expand Down
376 changes: 195 additions & 181 deletions llvm/docs/SourceLevelDebugging.rst

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions llvm/docs/TestingGuide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -741,16 +741,16 @@ RUN lines:

Expands to the path separator, i.e. ``:`` (or ``;`` on Windows).

``${fs-src-root}``
``%{fs-src-root}``
Expands to the root component of file system paths for the source directory,
i.e. ``/`` on Unix systems or ``C:\`` (or another drive) on Windows.

``${fs-tmp-root}``
``%{fs-tmp-root}``
Expands to the root component of file system paths for the test's temporary
directory, i.e. ``/`` on Unix systems or ``C:\`` (or another drive) on
Windows.

``${fs-sep}``
``%{fs-sep}``
Expands to the file system separator, i.e. ``/`` or ``\`` on Windows.

``%/s, %/S, %/t, %/T``
Expand Down
2 changes: 1 addition & 1 deletion llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ argument allocas in ``FunctionAST::codegen``.

Here we're first creating the variable, giving it the scope (``SP``),
the name, source location, type, and since it's an argument, the argument
index. Next, we create an ``lvm.dbg.declare`` call to indicate at the IR
index. Next, we create a ``#dbg_declare`` record to indicate at the IR
level that we've got a variable in an alloca (and it gives a starting
location for the variable), and setting a source location for the
beginning of the scope on the declare.
Expand Down
25 changes: 25 additions & 0 deletions llvm/include/llvm/ADT/APFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ struct APFloatBase {
// improved range compared to half (16-bit) formats, at (potentially)
// greater throughput than single precision (32-bit) formats.
S_FloatTF32,
// 6-bit floating point number with bit layout S1E3M2. Unlike IEEE-754
// types, there are no infinity or NaN values. The format is detailed in
// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
S_Float6E3M2FN,
// 6-bit floating point number with bit layout S1E2M3. Unlike IEEE-754
// types, there are no infinity or NaN values. The format is detailed in
// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
S_Float6E2M3FN,

S_x87DoubleExtended,
S_MaxSemantics = S_x87DoubleExtended,
Expand All @@ -209,6 +217,8 @@ struct APFloatBase {
static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
static const fltSemantics &FloatTF32() LLVM_READNONE;
static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
static const fltSemantics &x87DoubleExtended() LLVM_READNONE;

/// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
Expand Down Expand Up @@ -627,6 +637,8 @@ class IEEEFloat final : public APFloatBase {
APInt convertFloat8E4M3FNUZAPFloatToAPInt() const;
APInt convertFloat8E4M3B11FNUZAPFloatToAPInt() const;
APInt convertFloatTF32APFloatToAPInt() const;
APInt convertFloat6E3M2FNAPFloatToAPInt() const;
APInt convertFloat6E2M3FNAPFloatToAPInt() const;
void initFromAPInt(const fltSemantics *Sem, const APInt &api);
template <const fltSemantics &S> void initFromIEEEAPInt(const APInt &api);
void initFromHalfAPInt(const APInt &api);
Expand All @@ -642,6 +654,8 @@ class IEEEFloat final : public APFloatBase {
void initFromFloat8E4M3FNUZAPInt(const APInt &api);
void initFromFloat8E4M3B11FNUZAPInt(const APInt &api);
void initFromFloatTF32APInt(const APInt &api);
void initFromFloat6E3M2FNAPInt(const APInt &api);
void initFromFloat6E2M3FNAPInt(const APInt &api);

void assign(const IEEEFloat &);
void copySignificand(const IEEEFloat &);
Expand Down Expand Up @@ -1046,6 +1060,17 @@ class APFloat : public APFloatBase {
/// \param Semantics - type float semantics
static APFloat getAllOnesValue(const fltSemantics &Semantics);

static bool hasNanOrInf(const fltSemantics &Sem) {
switch (SemanticsToEnum(Sem)) {
default:
return true;
// Below Semantics do not support {NaN or Inf}
case APFloat::S_Float6E3M2FN:
case APFloat::S_Float6E2M3FN:
return false;
}
}

/// Used to insert APFloat objects, or objects that contain APFloat objects,
/// into FoldingSets.
void Profile(FoldingSetNodeID &NID) const;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/AsmParser/LLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ namespace llvm {

// Top-Level Entities
bool parseTopLevelEntities();
bool finalizeDebugInfoFormat(Module *M);
void dropUnknownMetadataReferences();
bool validateEndOfModule(bool UpgradeDebugInfo);
bool validateEndOfIndex();
Expand Down
124 changes: 82 additions & 42 deletions llvm/include/llvm/CodeGen/MachineDominators.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/Support/GenericDomTreeConstruction.h"
#include <cassert>
#include <memory>
#include <optional>

namespace llvm {
class AnalysisUsage;
Expand All @@ -39,16 +40,39 @@ inline void DominatorTreeBase<MachineBasicBlock, false>::addRoot(

extern template class DomTreeNodeBase<MachineBasicBlock>;
extern template class DominatorTreeBase<MachineBasicBlock, false>; // DomTree
extern template class DominatorTreeBase<MachineBasicBlock, true>; // PostDomTree

using MachineDomTree = DomTreeBase<MachineBasicBlock>;
using MachineDomTreeNode = DomTreeNodeBase<MachineBasicBlock>;

namespace DomTreeBuilder {
using MBBDomTree = DomTreeBase<MachineBasicBlock>;
using MBBUpdates = ArrayRef<llvm::cfg::Update<MachineBasicBlock *>>;
using MBBDomTreeGraphDiff = GraphDiff<MachineBasicBlock *, false>;

extern template void Calculate<MBBDomTree>(MBBDomTree &DT);
extern template void CalculateWithUpdates<MBBDomTree>(MBBDomTree &DT,
MBBUpdates U);

extern template void InsertEdge<MBBDomTree>(MBBDomTree &DT,
MachineBasicBlock *From,
MachineBasicBlock *To);

extern template void DeleteEdge<MBBDomTree>(MBBDomTree &DT,
MachineBasicBlock *From,
MachineBasicBlock *To);

extern template void ApplyUpdates<MBBDomTree>(MBBDomTree &DT,
MBBDomTreeGraphDiff &,
MBBDomTreeGraphDiff *);

extern template bool Verify<MBBDomTree>(const MBBDomTree &DT,
MBBDomTree::VerificationLevel VL);
} // namespace DomTreeBuilder

//===-------------------------------------
/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
/// compute a normal dominator tree.
///
class MachineDominatorTree : public MachineFunctionPass {
class MachineDominatorTree : public DomTreeBase<MachineBasicBlock> {
/// Helper structure used to hold all the basic blocks
/// involved in the split of a critical edge.
struct CriticalEdge {
Expand All @@ -70,70 +94,64 @@ class MachineDominatorTree : public MachineFunctionPass {
/// such as BB == elt.NewBB.
mutable SmallSet<MachineBasicBlock *, 32> NewBBs;

/// The DominatorTreeBase that is used to compute a normal dominator tree.
std::unique_ptr<MachineDomTree> DT;

/// Apply all the recorded critical edges to the DT.
/// This updates the underlying DT information in a way that uses
/// the fast query path of DT as much as possible.
/// FIXME: This method should not be a const member!
///
/// \post CriticalEdgesToSplit.empty().
void applySplitCriticalEdges() const;

public:
static char ID; // Pass ID, replacement for typeid
using Base = DomTreeBase<MachineBasicBlock>;

MachineDominatorTree();
explicit MachineDominatorTree(MachineFunction &MF) : MachineFunctionPass(ID) {
calculate(MF);
}
MachineDominatorTree() = default;
explicit MachineDominatorTree(MachineFunction &MF) { calculate(MF); }

MachineDomTree &getBase() {
if (!DT)
DT.reset(new MachineDomTree());
// FIXME: If there is an updater for MachineDominatorTree,
// migrate to this updater and remove these wrappers.

MachineDominatorTree &getBase() {
applySplitCriticalEdges();
return *DT;
return *this;
}

void getAnalysisUsage(AnalysisUsage &AU) const override;

MachineBasicBlock *getRoot() const {
applySplitCriticalEdges();
return DT->getRoot();
return Base::getRoot();
}

MachineDomTreeNode *getRootNode() const {
applySplitCriticalEdges();
return DT->getRootNode();
return const_cast<MachineDomTreeNode *>(Base::getRootNode());
}

bool runOnMachineFunction(MachineFunction &F) override;

void calculate(MachineFunction &F);

bool dominates(const MachineDomTreeNode *A,
const MachineDomTreeNode *B) const {
applySplitCriticalEdges();
return DT->dominates(A, B);
return Base::dominates(A, B);
}

void getDescendants(MachineBasicBlock *A,
SmallVectorImpl<MachineBasicBlock *> &Result) {
applySplitCriticalEdges();
DT->getDescendants(A, Result);
Base::getDescendants(A, Result);
}

bool dominates(const MachineBasicBlock *A, const MachineBasicBlock *B) const {
applySplitCriticalEdges();
return DT->dominates(A, B);
return Base::dominates(A, B);
}

// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
bool dominates(const MachineInstr *A, const MachineInstr *B) const {
applySplitCriticalEdges();
const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
if (BBA != BBB) return DT->dominates(BBA, BBB);
if (BBA != BBB)
return Base::dominates(BBA, BBB);

// Loop through the basic block until we find A or B.
MachineBasicBlock::const_iterator I = BBA->begin();
Expand All @@ -146,34 +164,34 @@ class MachineDominatorTree : public MachineFunctionPass {
bool properlyDominates(const MachineDomTreeNode *A,
const MachineDomTreeNode *B) const {
applySplitCriticalEdges();
return DT->properlyDominates(A, B);
return Base::properlyDominates(A, B);
}

bool properlyDominates(const MachineBasicBlock *A,
const MachineBasicBlock *B) const {
applySplitCriticalEdges();
return DT->properlyDominates(A, B);
return Base::properlyDominates(A, B);
}

/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
MachineBasicBlock *B) {
applySplitCriticalEdges();
return DT->findNearestCommonDominator(A, B);
return Base::findNearestCommonDominator(A, B);
}

MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
applySplitCriticalEdges();
return DT->getNode(BB);
return Base::getNode(BB);
}

/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
applySplitCriticalEdges();
return DT->getNode(BB);
return Base::getNode(BB);
}

/// addNewBlock - Add a new node to the dominator tree information. This
Expand All @@ -182,7 +200,7 @@ class MachineDominatorTree : public MachineFunctionPass {
MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
MachineBasicBlock *DomBB) {
applySplitCriticalEdges();
return DT->addNewBlock(BB, DomBB);
return Base::addNewBlock(BB, DomBB);
}

/// changeImmediateDominator - This method is used to update the dominator
Expand All @@ -191,43 +209,37 @@ class MachineDominatorTree : public MachineFunctionPass {
void changeImmediateDominator(MachineBasicBlock *N,
MachineBasicBlock *NewIDom) {
applySplitCriticalEdges();
DT->changeImmediateDominator(N, NewIDom);
Base::changeImmediateDominator(N, NewIDom);
}

void changeImmediateDominator(MachineDomTreeNode *N,
MachineDomTreeNode *NewIDom) {
applySplitCriticalEdges();
DT->changeImmediateDominator(N, NewIDom);
Base::changeImmediateDominator(N, NewIDom);
}

/// eraseNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
void eraseNode(MachineBasicBlock *BB) {
applySplitCriticalEdges();
DT->eraseNode(BB);
Base::eraseNode(BB);
}

/// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change.
void splitBlock(MachineBasicBlock* NewBB) {
applySplitCriticalEdges();
DT->splitBlock(NewBB);
Base::splitBlock(NewBB);
}

/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
bool isReachableFromEntry(const MachineBasicBlock *A) {
applySplitCriticalEdges();
return DT->isReachableFromEntry(A);
return Base::isReachableFromEntry(A);
}

void releaseMemory() override;

void verifyAnalysis() const override;

void print(raw_ostream &OS, const Module*) const override;

/// Record that the critical edge (FromBB, ToBB) has been
/// split with NewBB.
/// This is best to use this method instead of directly update the
Expand All @@ -251,6 +263,34 @@ class MachineDominatorTree : public MachineFunctionPass {
}
};

/// \brief Analysis pass which computes a \c MachineDominatorTree.
class MachineDominatorTreeWrapperPass : public MachineFunctionPass {
// MachineFunctionPass may verify the analysis result without running pass,
// e.g. when `F.hasAvailableExternallyLinkage` is true.
std::optional<MachineDominatorTree> DT;

public:
static char ID;

MachineDominatorTreeWrapperPass();

MachineDominatorTree &getDomTree() { return *DT; }
const MachineDominatorTree &getDomTree() const { return *DT; }

bool runOnMachineFunction(MachineFunction &MF) override;

void verifyAnalysis() const override;

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}

void releaseMemory() override;

void print(raw_ostream &OS, const Module *M = nullptr) const override;
};

//===-------------------------------------
/// DominatorTree GraphTraits specialization so the DominatorTree can be
/// iterable by generic graph iterators.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/MachineUniformityAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ using MachineUniformityInfo = GenericUniformityInfo<MachineSSAContext>;
/// everything is uniform.
MachineUniformityInfo computeMachineUniformityInfo(
MachineFunction &F, const MachineCycleInfo &cycleInfo,
const MachineDomTree &domTree, bool HasBranchDivergence);
const MachineDominatorTree &domTree, bool HasBranchDivergence);

/// Legacy analysis pass which computes a \ref MachineUniformityInfo.
class MachineUniformityAnalysisPass : public MachineFunctionPass {
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class DWARFFormValue {
const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
const DWARFContext *C = nullptr; /// Context for extract time.

DWARFFormValue(dwarf::Form F, ValueType V) : Form(F), Value(V) {}
DWARFFormValue(dwarf::Form F, const ValueType &V) : Form(F), Value(V) {}

public:
DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ struct TargetRegionEntryInfo {
unsigned DeviceID, unsigned FileID,
unsigned Line, unsigned Count);

bool operator<(const TargetRegionEntryInfo RHS) const {
bool operator<(const TargetRegionEntryInfo &RHS) const {
return std::make_tuple(ParentName, DeviceID, FileID, Line, Count) <
std::make_tuple(RHS.ParentName, RHS.DeviceID, RHS.FileID, RHS.Line,
RHS.Count);
Expand Down
11 changes: 2 additions & 9 deletions llvm/include/llvm/IR/MDBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ class MDBuilder {
//===------------------------------------------------------------------===//

/// Return metadata containing two branch weights.
/// @param TrueWeight the weight of the true branch
/// @param FalseWeight the weight of the false branch
/// @param Do these weights come from __builtin_expect*
MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight,
bool IsExpected = false);
MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight);

/// Return metadata containing two branch weights, with significant bias
/// towards `true` destination.
Expand All @@ -74,10 +70,7 @@ class MDBuilder {
MDNode *createUnlikelyBranchWeights();

/// Return metadata containing a number of branch weights.
/// @param Weights the weights of all the branches
/// @param Do these weights come from __builtin_expect*
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights,
bool IsExpected = false);
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights);

/// Return metadata specifying that a branch or switch is unpredictable.
MDNode *createUnpredictable();
Expand Down
17 changes: 1 addition & 16 deletions llvm/include/llvm/IR/ProfDataUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,6 @@ MDNode *getBranchWeightMDNode(const Instruction &I);
/// Nullptr otherwise.
MDNode *getValidBranchWeightMDNode(const Instruction &I);

/// Check if Branch Weight Metadata has an "expected" field from an llvm.expect*
/// intrinsic
bool hasBranchWeightOrigin(const Instruction &I);

/// Check if Branch Weight Metadata has an "expected" field from an llvm.expect*
/// intrinsic
bool hasBranchWeightOrigin(const MDNode *ProfileData);

/// Return the offset to the first branch weight data
unsigned getBranchWeightOffset(const MDNode *ProfileData);

/// Extract branch weights from MD_prof metadata
///
/// \param ProfileData A pointer to an MDNode.
Expand Down Expand Up @@ -122,11 +111,7 @@ bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalWeights);

/// Create a new `branch_weights` metadata node and add or overwrite
/// a `prof` metadata reference to instruction `I`.
/// \param I the Instruction to set branch weights on.
/// \param Weights an array of weights to set on instruction I.
/// \param IsExpected were these weights added from an llvm.expect* intrinsic.
void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights,
bool IsExpected);
void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights);

/// Scaling the profile data attached to 'I' using the ratio of S/T.
void scaleProfData(Instruction &I, uint64_t S, uint64_t T);
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void initializeMachineCopyPropagationPass(PassRegistry&);
void initializeMachineCycleInfoPrinterPassPass(PassRegistry &);
void initializeMachineCycleInfoWrapperPassPass(PassRegistry &);
void initializeMachineDominanceFrontierPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
void initializeMachineDominatorTreeWrapperPassPass(PassRegistry &);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
void initializeMachineFunctionSplitterPass(PassRegistry &);
void initializeMachineLateInstrsCleanupPass(PassRegistry&);
Expand Down
27 changes: 1 addition & 26 deletions llvm/include/llvm/MC/MCContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,31 +252,6 @@ class MCContext {
/// A collection of MCPseudoProbe in the current module
MCPseudoProbeTable PseudoProbeTable;

// Sections are differentiated by the quadruple (section_name, group_name,
// unique_id, link_to_symbol_name). Sections sharing the same quadruple are
// combined into one section.
struct ELFSectionKey {
std::string SectionName;
StringRef GroupName;
StringRef LinkedToName;
unsigned UniqueID;

ELFSectionKey(StringRef SectionName, StringRef GroupName,
StringRef LinkedToName, unsigned UniqueID)
: SectionName(SectionName), GroupName(GroupName),
LinkedToName(LinkedToName), UniqueID(UniqueID) {}

bool operator<(const ELFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
if (GroupName != Other.GroupName)
return GroupName < Other.GroupName;
if (int O = LinkedToName.compare(Other.LinkedToName))
return O < 0;
return UniqueID < Other.UniqueID;
}
};

struct COFFSectionKey {
std::string SectionName;
StringRef GroupName;
Expand Down Expand Up @@ -350,8 +325,8 @@ class MCContext {
};

StringMap<MCSectionMachO *> MachOUniquingMap;
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
StringMap<MCSectionELF *> ELFUniquingMap;
std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Support/MathExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,9 @@ std::enable_if_t<std::is_signed_v<T>, T> SubOverflow(T X, T Y, T &Result) {
/// result, returning true if an overflow ocurred.
template <typename T>
std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
#if __has_builtin(__builtin_mul_overflow)
return __builtin_mul_overflow(X, Y, &Result);
#else
// Perform the unsigned multiplication on absolute values.
using U = std::make_unsigned_t<T>;
const U UX = X < 0 ? (0 - static_cast<U>(X)) : static_cast<U>(X);
Expand All @@ -656,6 +659,7 @@ std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
return UX > (static_cast<U>(std::numeric_limits<T>::max()) + U(1)) / UY;
else
return UX > (static_cast<U>(std::numeric_limits<T>::max())) / UY;
#endif
}

} // namespace llvm
Expand Down
23 changes: 16 additions & 7 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,8 +866,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
ArrayRef<Constant *> Ops,
const DataLayout &DL,
const TargetLibraryInfo *TLI) {
bool InBounds = GEP->isInBounds();

Type *SrcElemTy = GEP->getSourceElementType();
Type *ResTy = GEP->getType();
if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy))
Expand Down Expand Up @@ -898,8 +896,10 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
InRange = InRange->sextOrTrunc(BitWidth);

// If this is a GEP of a GEP, fold it all into a single GEP.
GEPNoWrapFlags NW = GEP->getNoWrapFlags();
bool Overflow = false;
while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
InBounds &= GEP->isInBounds();
NW &= GEP->getNoWrapFlags();

SmallVector<Value *, 4> NestedOps(llvm::drop_begin(GEP->operands()));

Expand All @@ -923,9 +923,16 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,

Ptr = cast<Constant>(GEP->getOperand(0));
SrcElemTy = GEP->getSourceElementType();
Offset += APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps));
Offset = Offset.sadd_ov(
APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps)),
Overflow);
}

// Preserving nusw (without inbounds) also requires that the offset
// additions did not overflow.
if (NW.hasNoUnsignedSignedWrap() && !NW.isInBounds() && Overflow)
NW = NW.withoutNoUnsignedSignedWrap();

// If the base value for this address is a literal integer value, fold the
// getelementptr to the resulting integer value casted to the pointer type.
APInt BasePtr(BitWidth, 0);
Expand All @@ -944,17 +951,19 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
}

// Try to infer inbounds for GEPs of globals.
if (!InBounds && Offset.isNonNegative()) {
// TODO(gep_nowrap): Also infer nuw flag.
if (!NW.isInBounds() && Offset.isNonNegative()) {
bool CanBeNull, CanBeFreed;
uint64_t DerefBytes =
Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
InBounds = DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes);
if (DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes))
NW |= GEPNoWrapFlags::inBounds();
}

// Otherwise canonicalize this to a single ptradd.
LLVMContext &Ctx = Ptr->getContext();
return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Ptr,
ConstantInt::get(Ctx, Offset), InBounds,
ConstantInt::get(Ctx, Offset), NW,
InRange);
}

Expand Down
34 changes: 18 additions & 16 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ static std::string getTypeString(Type *T) {
return Tmp.str();
}

// Whatever debug info format we parsed, we should convert to the expected debug
// info format immediately afterwards.
bool LLParser::finalizeDebugInfoFormat(Module *M) {
// We should have already returned an error if we observed both intrinsics and
// records in this IR.
assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) &&
"Mixed debug intrinsics/records seen without a parsing error?");
if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) {
UseNewDbgInfoFormat = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormatToBitcode = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormat = SeenNewDbgInfoFormat;
} else if (M) {
M->setIsNewDbgInfoFormat(false);
}
return false;
}

/// Run: module ::= toplevelentity*
bool LLParser::Run(bool UpgradeDebugInfo,
DataLayoutCallbackTy DataLayoutCallback) {
Expand All @@ -91,7 +108,7 @@ bool LLParser::Run(bool UpgradeDebugInfo,
}

return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
validateEndOfIndex();
validateEndOfIndex() || finalizeDebugInfoFormat(M);
}

bool LLParser::parseStandaloneConstantValue(Constant *&C,
Expand Down Expand Up @@ -190,18 +207,6 @@ void LLParser::dropUnknownMetadataReferences() {
bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
if (!M)
return false;

// We should have already returned an error if we observed both intrinsics and
// records in this IR.
assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) &&
"Mixed debug intrinsics/records seen without a parsing error?");
if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) {
UseNewDbgInfoFormat = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormatToBitcode = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormat = SeenNewDbgInfoFormat;
M->setNewDbgInfoFormatFlag(SeenNewDbgInfoFormat);
}

// Handle any function attribute group forward references.
for (const auto &RAG : ForwardRefAttrGroups) {
Value *V = RAG.first;
Expand Down Expand Up @@ -434,9 +439,6 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
UpgradeModuleFlags(*M);
UpgradeSectionAttributes(*M);

if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE)
M->setIsNewDbgInfoFormat(UseNewDbgInfoFormat);

if (!Slots)
return false;
// Initialize the slot mapping.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4357,7 +4357,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE) {
TheModule->IsNewDbgInfoFormat =
UseNewDbgInfoFormat &&
LoadBitcodeIntoNewDbgInfoFormat != cl::boolOrDefault::BOU_FALSE;
LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_TRUE;
}

this->ValueTypeCallback = std::move(Callbacks.ValueType);
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1728,7 +1728,8 @@ void AsmPrinter::emitFunctionBody() {

if (isVerbose()) {
// Get MachineDominatorTree or compute it on the fly if it's unavailable
MDT = getAnalysisIfAvailable<MachineDominatorTree>();
auto MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
if (!MDT) {
OwnedMDT = std::make_unique<MachineDominatorTree>();
OwnedMDT->getBase().recalculate(*MF);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeMachineCopyPropagationPass(Registry);
initializeMachineCycleInfoPrinterPassPass(Registry);
initializeMachineCycleInfoWrapperPassPass(Registry);
initializeMachineDominatorTreePass(Registry);
initializeMachineDominatorTreeWrapperPassPass(Registry);
initializeMachineFunctionPrinterPassPass(Registry);
initializeMachineLateInstrsCleanupPass(Registry);
initializeMachineLICMPass(Registry);
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/CodeGenPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8866,8 +8866,7 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, ModifyDT &ModifiedDT) {
scaleWeights(NewTrueWeight, NewFalseWeight);
Br1->setMetadata(LLVMContext::MD_prof,
MDBuilder(Br1->getContext())
.createBranchWeights(TrueWeight, FalseWeight,
hasBranchWeightOrigin(*Br1)));
.createBranchWeights(TrueWeight, FalseWeight));

NewTrueWeight = TrueWeight;
NewFalseWeight = 2 * FalseWeight;
Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/CodeGen/EarlyIfConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,15 +790,15 @@ char &llvm::EarlyIfConverterID = EarlyIfConverter::ID;
INITIALIZE_PASS_BEGIN(EarlyIfConverter, DEBUG_TYPE,
"Early If Converter", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineTraceMetrics)
INITIALIZE_PASS_END(EarlyIfConverter, DEBUG_TYPE,
"Early If Converter", false, false)

void EarlyIfConverter::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineBranchProbabilityInfo>();
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
AU.addRequired<MachineTraceMetrics>();
Expand Down Expand Up @@ -1089,7 +1089,7 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
TRI = STI.getRegisterInfo();
SchedModel = STI.getSchedModel();
MRI = &MF.getRegInfo();
DomTree = &getAnalysis<MachineDominatorTree>();
DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
Loops = &getAnalysis<MachineLoopInfo>();
Traces = &getAnalysis<MachineTraceMetrics>();
MinInstr = nullptr;
Expand Down Expand Up @@ -1144,15 +1144,15 @@ char &llvm::EarlyIfPredicatorID = EarlyIfPredicator::ID;

INITIALIZE_PASS_BEGIN(EarlyIfPredicator, DEBUG_TYPE, "Early If Predicator",
false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
INITIALIZE_PASS_END(EarlyIfPredicator, DEBUG_TYPE, "Early If Predicator", false,
false)

void EarlyIfPredicator::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineBranchProbabilityInfo>();
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
Expand Down Expand Up @@ -1223,7 +1223,7 @@ bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
TRI = STI.getRegisterInfo();
MRI = &MF.getRegInfo();
SchedModel.init(&STI);
DomTree = &getAnalysis<MachineDominatorTree>();
DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
Loops = &getAnalysis<MachineLoopInfo>();
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();

Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/CodeGen/InlineSpiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
VirtRegMap &vrm)
: MF(mf), LIS(pass.getAnalysis<LiveIntervals>()),
LSS(pass.getAnalysis<LiveStacks>()),
MDT(pass.getAnalysis<MachineDominatorTree>()), VRM(vrm),
MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
MDT(pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
VRM(vrm), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
TRI(*mf.getSubtarget().getRegisterInfo()),
MBFI(pass.getAnalysis<MachineBlockFrequencyInfo>()),
IPA(LIS, mf.getNumBlockIDs()) {}
Expand Down Expand Up @@ -192,8 +192,8 @@ class InlineSpiller : public Spiller {
VirtRegAuxInfo &VRAI)
: MF(MF), LIS(Pass.getAnalysis<LiveIntervals>()),
LSS(Pass.getAnalysis<LiveStacks>()),
MDT(Pass.getAnalysis<MachineDominatorTree>()), VRM(VRM),
MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
MDT(Pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
VRM(VRM), MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
TRI(*MF.getSubtarget().getRegisterInfo()),
MBFI(Pass.getAnalysis<MachineBlockFrequencyInfo>()),
HSpiller(Pass, MF, VRM), VRAI(VRAI) {}
Expand Down Expand Up @@ -1381,17 +1381,17 @@ void HoistSpillHelper::rmRedundantSpills(
// earlier spill with smaller SlotIndex.
for (auto *const CurrentSpill : Spills) {
MachineBasicBlock *Block = CurrentSpill->getParent();
MachineDomTreeNode *Node = MDT.getBase().getNode(Block);
MachineDomTreeNode *Node = MDT.getNode(Block);
MachineInstr *PrevSpill = SpillBBToSpill[Node];
if (PrevSpill) {
SlotIndex PIdx = LIS.getInstructionIndex(*PrevSpill);
SlotIndex CIdx = LIS.getInstructionIndex(*CurrentSpill);
MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
SpillsToRm.push_back(SpillToRm);
SpillBBToSpill[MDT.getBase().getNode(Block)] = SpillToKeep;
SpillBBToSpill[MDT.getNode(Block)] = SpillToKeep;
} else {
SpillBBToSpill[MDT.getBase().getNode(Block)] = CurrentSpill;
SpillBBToSpill[MDT.getNode(Block)] = CurrentSpill;
}
}
for (auto *const SpillToRm : SpillsToRm)
Expand Down Expand Up @@ -1465,7 +1465,7 @@ void HoistSpillHelper::getVisitOrders(
// Sort the nodes in WorkSet in top-down order and save the nodes
// in Orders. Orders will be used for hoisting in runHoistSpills.
unsigned idx = 0;
Orders.push_back(MDT.getBase().getNode(Root));
Orders.push_back(MDT.getNode(Root));
do {
MachineDomTreeNode *Node = Orders[idx++];
for (MachineDomTreeNode *Child : Node->children()) {
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const {

auto &MBPI = getAnalysis<MachineBranchProbabilityInfo>();
auto *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
auto *MDT = getAnalysisIfAvailable<MachineDominatorTree>();
auto *MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
auto *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
LLVM_DEBUG(dbgs() << "Building MachineBlockFrequencyInfo on the fly\n");
LLVM_DEBUG(if (MLI) dbgs() << "LoopInfo is available\n");

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/LiveDebugVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ char LiveDebugVariables::ID = 0;

INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_END(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)

void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineDominatorTree>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addRequiredTransitive<LiveIntervals>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/LiveIntervals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ char LiveIntervals::ID = 0;
char &llvm::LiveIntervalsID = LiveIntervals::ID;
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals", "Live Interval Analysis",
false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
"Live Interval Analysis", false, false)
Expand Down Expand Up @@ -123,7 +123,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
TRI = MF->getSubtarget().getRegisterInfo();
TII = MF->getSubtarget().getInstrInfo();
Indexes = &getAnalysis<SlotIndexes>();
DomTree = &getAnalysis<MachineDominatorTree>();
DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();

if (!LICalc)
LICalc = new LiveIntervalCalc();
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/MIRSampleProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ INITIALIZE_PASS_BEGIN(MIRProfileLoaderPass, DEBUG_TYPE,
"Load MIR Sample Profile",
/* cfg = */ false, /* is_analysis = */ false)
INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
Expand Down Expand Up @@ -365,7 +365,7 @@ bool MIRProfileLoaderPass::runOnMachineFunction(MachineFunction &MF) {
<< MF.getFunction().getName() << "\n");
MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
MIRSampleLoader->setInitVals(
&getAnalysis<MachineDominatorTree>(),
&getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(),
&getAnalysis<MachinePostDominatorTree>(), &getAnalysis<MachineLoopInfo>(),
MBFI, &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE());

Expand Down Expand Up @@ -400,7 +400,7 @@ bool MIRProfileLoaderPass::doInitialization(Module &M) {
void MIRProfileLoaderPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineBlockFrequencyInfo>();
AU.addRequired<MachineDominatorTree>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachinePostDominatorTree>();
AU.addRequiredTransitive<MachineLoopInfo>();
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/MachineBasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1330,9 +1330,9 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
LIS->repairIntervalsInRange(this, getFirstTerminator(), end(), UsedRegs);
}

if (MachineDominatorTree *MDT =
P.getAnalysisIfAvailable<MachineDominatorTree>())
MDT->recordSplitCriticalEdge(this, Succ, NMBB);
if (auto *MDTWrapper =
P.getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>())
MDTWrapper->getDomTree().recordSplitCriticalEdge(this, Succ, NMBB);

if (MachineLoopInfo *MLI = P.getAnalysisIfAvailable<MachineLoopInfo>())
if (MachineLoop *TIL = MLI->getLoopFor(this)) {
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/MachineCSE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ namespace {
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<AAResultsWrapperPass>();
AU.addPreservedID(MachineLoopInfoID);
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineBlockFrequencyInfo>();
AU.addPreserved<MachineBlockFrequencyInfo>();
}
Expand Down Expand Up @@ -166,7 +166,7 @@ char &llvm::MachineCSEID = MachineCSE::ID;

INITIALIZE_PASS_BEGIN(MachineCSE, DEBUG_TYPE,
"Machine Common Subexpression Elimination", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(MachineCSE, DEBUG_TYPE,
"Machine Common Subexpression Elimination", false, false)
Expand Down Expand Up @@ -943,7 +943,7 @@ bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
TRI = MF.getSubtarget().getRegisterInfo();
MRI = &MF.getRegInfo();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
DT = &getAnalysis<MachineDominatorTree>();
DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
LookAheadLimit = TII->getMachineCSELookAheadLimit();
bool ChangedPRE, ChangedCSE;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ INITIALIZE_PASS_END(MachineCombiner, DEBUG_TYPE, "Machine InstCombiner",

void MachineCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addPreserved<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
AU.addRequired<MachineTraceMetrics>();
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/CodeGen/MachineDominanceFrontier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ char MachineDominanceFrontier::ID = 0;

INITIALIZE_PASS_BEGIN(MachineDominanceFrontier, "machine-domfrontier",
"Machine Dominance Frontier Construction", true, true)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_END(MachineDominanceFrontier, "machine-domfrontier",
"Machine Dominance Frontier Construction", true, true)

Expand All @@ -38,7 +38,8 @@ char &llvm::MachineDominanceFrontierID = MachineDominanceFrontier::ID;

bool MachineDominanceFrontier::runOnMachineFunction(MachineFunction &) {
releaseMemory();
Base.analyze(getAnalysis<MachineDominatorTree>().getBase());
Base.analyze(
getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree().getBase());
return false;
}

Expand All @@ -48,6 +49,6 @@ void MachineDominanceFrontier::releaseMemory() {

void MachineDominanceFrontier::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineDominatorTree>();
AU.addRequired<MachineDominatorTreeWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
73 changes: 42 additions & 31 deletions llvm/lib/CodeGen/MachineDominators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,59 @@ static cl::opt<bool, true> VerifyMachineDomInfoX(
namespace llvm {
template class DomTreeNodeBase<MachineBasicBlock>;
template class DominatorTreeBase<MachineBasicBlock, false>; // DomTreeBase
}

char MachineDominatorTree::ID = 0;
namespace DomTreeBuilder {
template void Calculate<MBBDomTree>(MBBDomTree &DT);
template void CalculateWithUpdates<MBBDomTree>(MBBDomTree &DT, MBBUpdates U);

INITIALIZE_PASS(MachineDominatorTree, "machinedomtree",
"MachineDominator Tree Construction", true, true)
template void InsertEdge<MBBDomTree>(MBBDomTree &DT, MachineBasicBlock *From,
MachineBasicBlock *To);

char &llvm::MachineDominatorsID = MachineDominatorTree::ID;
template void DeleteEdge<MBBDomTree>(MBBDomTree &DT, MachineBasicBlock *From,
MachineBasicBlock *To);

void MachineDominatorTree::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
template void ApplyUpdates<MBBDomTree>(MBBDomTree &DT, MBBDomTreeGraphDiff &,
MBBDomTreeGraphDiff *);

template bool Verify<MBBDomTree>(const MBBDomTree &DT,
MBBDomTree::VerificationLevel VL);
} // namespace DomTreeBuilder
}

bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) {
calculate(F);
return false;
char MachineDominatorTreeWrapperPass::ID = 0;

INITIALIZE_PASS(MachineDominatorTreeWrapperPass, "machinedomtree",
"MachineDominator Tree Construction", true, true)

MachineDominatorTreeWrapperPass::MachineDominatorTreeWrapperPass()
: MachineFunctionPass(ID) {
initializeMachineDominatorTreeWrapperPassPass(
*PassRegistry::getPassRegistry());
}

void MachineDominatorTree::calculate(MachineFunction &F) {
CriticalEdgesToSplit.clear();
NewBBs.clear();
DT.reset(new DomTreeBase<MachineBasicBlock>());
DT->recalculate(F);
recalculate(F);
}

MachineDominatorTree::MachineDominatorTree()
: MachineFunctionPass(ID) {
initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry());
}
char &llvm::MachineDominatorsID = MachineDominatorTreeWrapperPass::ID;

void MachineDominatorTree::releaseMemory() {
CriticalEdgesToSplit.clear();
DT.reset(nullptr);
bool MachineDominatorTreeWrapperPass::runOnMachineFunction(MachineFunction &F) {
DT = MachineDominatorTree(F);
return false;
}

void MachineDominatorTree::verifyAnalysis() const {
if (DT && VerifyMachineDomInfo)
if (!DT->verify(MachineDomTree::VerificationLevel::Basic)) {
errs() << "MachineDominatorTree verification failed\n";
abort();
}
void MachineDominatorTreeWrapperPass::releaseMemory() { DT.reset(); }

void MachineDominatorTreeWrapperPass::verifyAnalysis() const {
if (VerifyMachineDomInfo && DT)
if (!DT->verify(MachineDominatorTree::VerificationLevel::Basic))
report_fatal_error("MachineDominatorTree verification failed!");
}

void MachineDominatorTree::print(raw_ostream &OS, const Module*) const {
void MachineDominatorTreeWrapperPass::print(raw_ostream &OS,
const Module *) const {
if (DT)
DT->print(OS);
}
Expand All @@ -103,7 +111,7 @@ void MachineDominatorTree::applySplitCriticalEdges() const {
for (CriticalEdge &Edge : CriticalEdgesToSplit) {
// Update dominator information.
MachineBasicBlock *Succ = Edge.ToBB;
MachineDomTreeNode *SuccDTNode = DT->getNode(Succ);
MachineDomTreeNode *SuccDTNode = Base::getNode(Succ);

for (MachineBasicBlock *PredBB : Succ->predecessors()) {
if (PredBB == Edge.NewBB)
Expand All @@ -126,7 +134,7 @@ void MachineDominatorTree::applySplitCriticalEdges() const {
"than one predecessor!");
PredBB = *PredBB->pred_begin();
}
if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) {
if (!Base::dominates(SuccDTNode, Base::getNode(PredBB))) {
IsNewIDom[Idx] = false;
break;
}
Expand All @@ -138,13 +146,16 @@ void MachineDominatorTree::applySplitCriticalEdges() const {
Idx = 0;
for (CriticalEdge &Edge : CriticalEdgesToSplit) {
// We know FromBB dominates NewBB.
MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB);
MachineDomTreeNode *NewDTNode =
const_cast<MachineDominatorTree *>(this)->Base::addNewBlock(
Edge.NewBB, Edge.FromBB);

// If all the other predecessors of "Succ" are dominated by "Succ" itself
// then the new block is the new immediate dominator of "Succ". Otherwise,
// the new block doesn't dominate anything.
if (IsNewIDom[Idx])
DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode);
const_cast<MachineDominatorTree *>(this)->Base::changeImmediateDominator(
Base::getNode(Edge.ToBB), NewDTNode);
++Idx;
}
NewBBs.clear();
Expand Down
Loading