Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable
codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml
codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
}
}

#[derive(Diagnostic)]
#[diag(codegen_llvm_autodiff_without_lto)]
pub(crate) struct AutoDiffWithoutLto;

#[derive(Diagnostic)]
#[diag(codegen_llvm_autodiff_without_enable)]
pub(crate) struct AutoDiffWithoutEnable;
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::abi::FnAbiLlvmExt;
use crate::builder::Builder;
use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call};
use crate::context::CodegenCx;
use crate::errors::AutoDiffWithoutEnable;
use crate::errors::{AutoDiffWithoutEnable, AutoDiffWithoutLto};
use crate::llvm::{self, Metadata, Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::va_arg::emit_va_arg;
Expand Down Expand Up @@ -1146,6 +1146,9 @@ fn codegen_autodiff<'ll, 'tcx>(
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
}
if tcx.sess.lto() != rustc_session::config::Lto::Fat {
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto);
}

let fn_args = instance.args;
let callee_ty = instance.ty(tcx, bx.typing_env());
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,14 +594,6 @@ impl Session {

/// Calculates the flavor of LTO to use for this compilation.
pub fn lto(&self) -> config::Lto {
// Autodiff currently requires fat-lto to have access to the llvm-ir of all (indirectly) used functions and types.
// fat-lto is the easiest solution to this requirement, but quite expensive.
// FIXME(autodiff): Make autodiff also work with embed-bc instead of fat-lto.
// Don't apply fat-lto to proc-macro crates as they cannot use fat-lto without -Zdylib-lto
if self.opts.autodiff_enabled() && !self.opts.crate_types.contains(&CrateType::ProcMacro) {
return config::Lto::Fat;
}

// If our target has codegen requirements ignore the command line
if self.target.requires_lto {
return config::Lto::Fat;
Expand Down
8 changes: 8 additions & 0 deletions src/ci/docker/host-x86_64/pr-check-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
mingw-w64 \
&& rm -rf /var/lib/apt/lists/*

RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz | \
tar -xz
ENV WASI_SDK_PATH=/wasi-sdk-27.0-x86_64-linux

ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3"

COPY scripts/sccache.sh /scripts/
Expand All @@ -30,6 +34,10 @@ ENV SCRIPT \
python3 ../x.py check && \
python3 ../x.py clippy ci --stage 2 && \
python3 ../x.py test --stage 1 core alloc std test proc_macro && \
# Elsewhere, we run all tests for the host. A number of codegen tests are sensitive to the target pointer
# width, for example because they mention a usize. wasm32-wasip1 in test-various, so using it here can't make
# PR CI more strict than full CI.
python3 ../x.py test --stage 1 tests/codegen-llvm --target wasm32-wasip1 && \
python3 ../x.py test --stage 1 src/tools/compiletest && \
python3 ../x.py doc bootstrap --stage 1 && \
# Build both public and internal documentation.
Expand Down
3 changes: 2 additions & 1 deletion src/etc/lldb_commands
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Forces test-compliant formatting to all other types
type synthetic add -l lldb_lookup.synthetic_lookup -x ".*" --category Rust
type summary add -F _ -e -x -h "^.*$" --category Rust
# Std String
type synthetic add -l lldb_lookup.StdStringSyntheticProvider -x "^(alloc::([a-z_]+::)+)String$" --category Rust
type summary add -F lldb_lookup.StdStringSummaryProvider -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust
Expand Down Expand Up @@ -66,6 +65,7 @@ type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::([a-z_]+::)+)Pa
type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust
type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust
# Enum
# type summary add -F lldb_lookup.ClangEncodedEnumSummaryProvider -e -h "lldb_lookup.is_sum_type_enum" --recognizer-function --category Rust
## MSVC
type synthetic add -l lldb_lookup.MSVCEnumSyntheticProvider -x "^enum2\$<.+>$" --category Rust
type summary add -F lldb_lookup.MSVCEnumSummaryProvider -e -x -h "^enum2\$<.+>$" --category Rust
Expand All @@ -74,6 +74,7 @@ type synthetic add -l lldb_lookup.synthetic_lookup -x "^enum2\$<.+>::.*$" --cate
type summary add -F lldb_lookup.summary_lookup -e -x -h "^enum2\$<.+>::.*$" --category Rust
# Tuple
type synthetic add -l lldb_lookup.synthetic_lookup -x "^\(.*\)$" --category Rust
type summary add -F lldb_lookup.TupleSummaryProvider -e -x -h "^\(.*\)$" --category Rust
## MSVC
type synthetic add -l lldb_lookup.MSVCTupleSyntheticProvider -x "^tuple\$<.+>$" --category Rust
type summary add -F lldb_lookup.TupleSummaryProvider -e -x -h "^tuple\$<.+>$" --category Rust
Expand Down
23 changes: 20 additions & 3 deletions src/etc/lldb_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ def is_hashbrown_hashmap(hash_map: lldb.SBValue) -> bool:


def classify_rust_type(type: lldb.SBType) -> str:
if type.IsPointerType():
type = type.GetPointeeType()

type_class = type.GetTypeClass()
if type_class == lldb.eTypeClassStruct:
return classify_struct(type.name, type.fields)
Expand Down Expand Up @@ -88,6 +85,26 @@ def synthetic_lookup(valobj: lldb.SBValue, _dict: LLDBOpaque) -> object:
if rust_type == RustType.SINGLETON_ENUM:
return synthetic_lookup(valobj.GetChildAtIndex(0), _dict)
if rust_type == RustType.ENUM:
# this little trick lets us treat `synthetic_lookup` as a "recognizer function" for the enum
# summary providers, reducing the number of lookups we have to do. This is a huge time save
# because there's no way (via type name) to recognize sum-type enums on `*-gnu` targets. The
# alternative would be to shove every single type through `summary_lookup`, which is
# incredibly wasteful. Once these scripts are updated for LLDB 19.0 and we can use
# `--recognizer-function`, this hack will only be needed for backwards compatibility.
summary: lldb.SBTypeSummary = valobj.GetTypeSummary()
if (
summary.summary_data is None
or summary.summary_data.strip()
!= "lldb_lookup.ClangEncodedEnumSummaryProvider(valobj,internal_dict)"
):
rust_category: lldb.SBTypeCategory = lldb.debugger.GetCategory("Rust")
rust_category.AddTypeSummary(
lldb.SBTypeNameSpecifier(valobj.GetTypeName()),
lldb.SBTypeSummary().CreateWithFunctionName(
"lldb_lookup.ClangEncodedEnumSummaryProvider"
),
)

return ClangEncodedEnumProvider(valobj, _dict)
if rust_type == RustType.STD_VEC:
return StdVecSyntheticProvider(valobj, _dict)
Expand Down
122 changes: 73 additions & 49 deletions src/etc/lldb_providers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations
import re
import sys
from typing import List, TYPE_CHECKING, Generator
from typing import Generator, List, TYPE_CHECKING

from lldb import (
SBData,
Expand All @@ -12,6 +11,8 @@
eFormatChar,
)

from rust_types import is_tuple_fields

if TYPE_CHECKING:
from lldb import SBValue, SBType, SBTypeStaticField, SBTarget

Expand Down Expand Up @@ -206,6 +207,34 @@ def resolve_msvc_template_arg(arg_name: str, target: SBTarget) -> SBType:
return result


def StructSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# structs need the field name before the field value
output = (
f"{valobj.GetChildAtIndex(i).GetName()}:{child}"
for i, child in enumerate(aggregate_field_summary(valobj, _dict))
)

return "{" + ", ".join(output) + "}"


def TupleSummaryProvider(valobj: SBValue, _dict: LLDBOpaque):
return "(" + ", ".join(aggregate_field_summary(valobj, _dict)) + ")"


def aggregate_field_summary(valobj: SBValue, _dict) -> Generator[str, None, None]:
for i in range(0, valobj.GetNumChildren()):
child: SBValue = valobj.GetChildAtIndex(i)
summary = child.summary
if summary is None:
summary = child.value
if summary is None:
if is_tuple_fields(child):
summary = TupleSummaryProvider(child, _dict)
else:
summary = StructSummaryProvider(child, _dict)
yield summary


def SizeSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
return "size=" + str(valobj.GetNumChildren())

Expand Down Expand Up @@ -454,49 +483,55 @@ def get_type_name(self):
return "&str"


def _getVariantName(variant) -> str:
def _getVariantName(variant: SBValue) -> str:
"""
Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
we can extract `TheVariantName` from it for display purpose.
"""
s = variant.GetType().GetName()
match = re.search(r"::([^:]+)\$Variant$", s)
return match.group(1) if match else ""
if not s.endswith("$Variant"):
return ""

# trim off path and "$Variant"
# len("$Variant") == 8
return s.rsplit("::", 1)[1][:-8]


class ClangEncodedEnumProvider:
"""Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""

valobj: SBValue
variant: SBValue
value: SBValue

DISCRIMINANT_MEMBER_NAME = "$discr$"
VALUE_MEMBER_NAME = "value"

__slots__ = ("valobj", "variant", "value")

def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.update()

def has_children(self) -> bool:
return True
return self.value.MightHaveChildren()

def num_children(self) -> int:
return 1
return self.value.GetNumChildren()

def get_child_index(self, _name: str) -> int:
return -1
def get_child_index(self, name: str) -> int:
return self.value.GetIndexOfChildWithName(name)

def get_child_at_index(self, index: int) -> SBValue:
if index == 0:
value = self.variant.GetChildMemberWithName(
ClangEncodedEnumProvider.VALUE_MEMBER_NAME
)
return value.CreateChildAtOffset(
_getVariantName(self.variant), 0, value.GetType()
)
return None
return self.value.GetChildAtIndex(index)

def update(self):
all_variants = self.valobj.GetChildAtIndex(0)
index = self._getCurrentVariantIndex(all_variants)
self.variant = all_variants.GetChildAtIndex(index)
self.value = self.variant.GetChildMemberWithName(
ClangEncodedEnumProvider.VALUE_MEMBER_NAME
).GetSyntheticValue()

def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
default_index = 0
Expand All @@ -514,6 +549,23 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
return default_index


def ClangEncodedEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
enum_synth = ClangEncodedEnumProvider(valobj.GetNonSyntheticValue(), _dict)
variant = enum_synth.variant
name = _getVariantName(variant)

if valobj.GetNumChildren() == 0:
return name

child_name: str = valobj.GetChildAtIndex(0).name
if child_name == "0" or child_name == "__0":
# enum variant is a tuple struct
return name + TupleSummaryProvider(valobj, _dict)
else:
# enum variant is a regular struct
return name + StructSummaryProvider(valobj, _dict)


class MSVCEnumSyntheticProvider:
"""
Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
Expand All @@ -522,12 +574,14 @@ class MSVCEnumSyntheticProvider:
https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
"""

valobj: SBValue
variant: SBValue
value: SBValue

__slots__ = ["valobj", "variant", "value"]

def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.variant: SBValue
self.value: SBValue
self.update()

def update(self):
Expand Down Expand Up @@ -695,21 +749,6 @@ def get_type_name(self) -> str:
return name


def StructSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
output = []
for i in range(valobj.GetNumChildren()):
child: SBValue = valobj.GetChildAtIndex(i)
summary = child.summary
if summary is None:
summary = child.value
if summary is None:
summary = StructSummaryProvider(child, _dict)
summary = child.GetName() + ":" + summary
output.append(summary)

return "{" + ", ".join(output) + "}"


def MSVCEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
enum_synth = MSVCEnumSyntheticProvider(valobj.GetNonSyntheticValue(), _dict)
variant_names: SBType = valobj.target.FindFirstType(
Expand Down Expand Up @@ -826,21 +865,6 @@ def get_type_name(self) -> str:
return "(" + name + ")"


def TupleSummaryProvider(valobj: SBValue, _dict: LLDBOpaque):
output: List[str] = []

for i in range(0, valobj.GetNumChildren()):
child: SBValue = valobj.GetChildAtIndex(i)
summary = child.summary
if summary is None:
summary = child.value
if summary is None:
summary = "{...}"
output.append(summary)

return "(" + ", ".join(output) + ")"


class StdVecSyntheticProvider:
"""Pretty-printer for alloc::vec::Vec<T>

Expand Down
9 changes: 4 additions & 5 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2766,12 +2766,11 @@ impl<'test> TestCx<'test> {
.map_err(|err| format!("failed to load expected output from `{}`: {}", path, err))
}

/// Attempts to delete a file, succeeding if the file does not exist.
fn delete_file(&self, file: &Utf8Path) {
if !file.exists() {
// Deleting a nonexistent file would error.
return;
}
if let Err(e) = fs::remove_file(file.as_std_path()) {
if let Err(e) = fs::remove_file(file.as_std_path())
&& e.kind() != io::ErrorKind::NotFound
{
self.fatal(&format!("failed to delete `{}`: {}", file, e,));
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/basic-types-globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// lldb-command:v I
// lldb-check: ::I::[...] = -1
// lldb-command:v --format=d C
// lldb-check: ::C::[...] = 97
// lldb-check: ::C::[...] = 97 U+0x00000061 U'a'
// lldb-command:v --format=d I8
// lldb-check: ::I8::[...] = 68
// lldb-command:v I16
Expand Down
6 changes: 3 additions & 3 deletions tests/debuginfo/borrowed-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
// lldb-command:run

// lldb-command:v *the_a_ref
// lldb-check:(borrowed_enum::ABC) *the_a_ref = { TheA = { x = 0 y = 8970181431921507452 } }
// lldb-check:(borrowed_enum::ABC) *the_a_ref = TheA{x:0, y:8970181431921507452} { x = 0 y = 8970181431921507452 }
// lldb-command:v *the_b_ref
// lldb-check:(borrowed_enum::ABC) *the_b_ref = { TheB = { 0 = 0 1 = 286331153 2 = 286331153 } }
// lldb-check:(borrowed_enum::ABC) *the_b_ref = TheB(0, 286331153, 286331153) { 0 = 0 1 = 286331153 2 = 286331153 }
// lldb-command:v *univariant_ref
// lldb-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { 0 = 4820353753753434 } }
// lldb-check:(borrowed_enum::Univariant) *univariant_ref = TheOnlyCase(4820353753753434) { 0 = 4820353753753434 }

#![allow(unused_variables)]

Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/c-style-enum-in-composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
// lldb-check:[...] { 0 = 0 1 = OneHundred }

// lldb-command:v tuple_padding_at_end
// lldb-check:[...] { 0 = { 0 = 1 1 = OneThousand } 1 = 2 }
// lldb-check:[...] ((1, OneThousand), 2) { 0 = (1, OneThousand) { 0 = 1 1 = OneThousand } 1 = 2 }

// lldb-command:v tuple_different_enums
// lldb-check:[...] { 0 = OneThousand 1 = MountainView 2 = OneMillion 3 = Vienna }
Expand Down
Loading
Loading