inkwell icon indicating copy to clipboard operation
inkwell copied to clipboard

Add debug information utility functions and support Metadata on Operands

Open jaynus opened this issue 2 months ago • 4 comments

Description

Adds a few utility functions around debug information and changes instruction operand handling to support debug metadata, with some fixes to error messaging around value types too.

Changes

  • Changes InstructionValue::get_operand family of functions (including get_operands) to return a new OperandValue. They currently had Either<BasicValue, BasicBlock> which is insufficient for operands - they can be metadata values as well.
  • Added Helper functions for the transitional DbgRecord changes.
    Module::is_new_debug_format - this corresponds to LLVMIsNewDbgInfoFormat Module::set_new_debug_format - this corresponds to LLVMSetIsNewDbgInfoFormat
  • Added as_metadata_value to the suite of DI* types, as all these types are metadata values that can be fetched via instruction operands (old) or DbgRecord (new)
  • Better output to the panics in the enum variants, so you can see what kind was unimplemente
  • Updated tests to all pass for the new get_operand call.

How This Has Been Tested

This was tested with llvm 20.1 locally in a personal project. Ex usage such as:

    module.set_new_debug_format(false);
    module.get_functions().for_each(|function| {
        function.get_basic_blocks().iter().for_each(|block| {
            block.get_instructions().skip(1).for_each(|instr| {
                    (0..instr.get_num_operands()).for_each(|i| {
                            if let Some(OperandValue::BasicMetadataValue(metadata)) =
                                instr.get_operand(i)
                            {
                                ... Handle debug metadata operands here....
                            }
                        });
                    });
                }
            });
        });

Breaking Changes

Changes InstructionValue::get_operand and OperandIter to use OperandValue instead of Either<BasicValue, BasicBlock>. This was required because operands on a value instruction can be more than just BasicValue or BasicBlock, they can also be MetadataValue in the case of debug intrinsics.

  • All left() calls must now be into_basic_value() or try_into() or into()
  • All right() calls must now be into_basic_block() or try_into() or into()

Checklist

jaynus avatar Oct 02 '25 22:10 jaynus

There are some tests that are failing and need to be fixed

TheDan64 avatar Oct 10 '25 19:10 TheDan64

@jaynus are you able to fix the tests?

TheDan64 avatar Oct 21 '25 06:10 TheDan64

@jaynus bump, would like to get this into the upcoming release if possible

TheDan64 avatar Nov 01 '25 22:11 TheDan64

@jaynus, if you ever get around to finishing this up, I just want to apologize for creating a merge conflict. You see, I thought your idea of using the OperandValue enum was a good idea, and I decided to go ahead and replace all instances of Either with a specialized enum, but I didn't realize that your PR hadn't been merged yet, so unfortunately I wrote code that will conflict with your code, and now my PR has been merged. Sorry for stepping on your toes.

ErisianArchitect avatar Nov 06 '25 01:11 ErisianArchitect