From evan.cheng at apple.com Mon Feb 27 00:52:16 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 27 Feb 2006 00:52:16 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200602270652.AAA09232@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.193 -> 1.194 --- Log message: Pass -mdynamic-no-pic to build cbe executable. --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.193 llvm-test/Makefile.programs:1.194 --- llvm-test/Makefile.programs:1.193 Fri Feb 17 18:02:32 2006 +++ llvm-test/Makefile.programs Mon Feb 27 00:52:04 2006 @@ -282,7 +282,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.cbe): \ Output/%.cbe: Output/%.cbe.c - -$(CC) $< $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -O2 -o $@ + -$(CC) $< $(LDFLAGS) $(CFLAGS) -fno-strict-aliasing -O2 $(TARGET_CFLAGS) -o $@ # # Compile a linked program to machine code with LLC. From jlaskey at apple.com Mon Feb 27 04:29:17 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 04:29:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Message-ID: <200602271029.EAA18774@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaAsmPrinter.cpp updated: 1.31 -> 1.32 --- Log message: Removed dependency on how operands are printed (want multi-line.) --- Diffs of the changes: (+3 -9) AlphaAsmPrinter.cpp | 12 +++--------- 1 files changed, 3 insertions(+), 9 deletions(-) Index: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp diff -u llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.31 llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.32 --- llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.31 Mon Feb 6 11:15:17 2006 +++ llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Mon Feb 27 04:29:04 2006 @@ -246,10 +246,8 @@ O << "\t.local " << name << "\n"; O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) - << "," << (1 << Align); - O << "\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << "\n"; + << "," << (1 << Align) + << "\n"; } else { switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: @@ -278,11 +276,7 @@ EmitAlignment(Align); O << "\t.type " << name << ", at object\n"; O << "\t.size " << name << "," << Size << "\n"; - O << name << ":\t\t\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); - O << "\n"; + O << name << ":\n"; EmitGlobalConstant(C); } } From jlaskey at apple.com Mon Feb 27 04:34:06 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 04:34:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200602271034.EAA19192@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.193 -> 1.194 --- Log message: Pretty print large struct constants. --- Diffs of the changes: (+10 -1) AsmWriter.cpp | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.193 llvm/lib/VMCore/AsmWriter.cpp:1.194 --- llvm/lib/VMCore/AsmWriter.cpp:1.193 Sun Feb 26 04:16:05 2006 +++ llvm/lib/VMCore/AsmWriter.cpp Mon Feb 27 04:33:53 2006 @@ -419,6 +419,8 @@ bool PrintName, std::map &TypeTable, SlotMachine *Machine) { + const int IndentSize = 4; + static std::string Indent = "\n"; if (const ConstantBool *CB = dyn_cast(CV)) { Out << (CB == ConstantBool::True ? "true" : "false"); } else if (const ConstantSInt *CI = dyn_cast(CV)) { @@ -484,7 +486,12 @@ Out << '{'; unsigned N = CS->getNumOperands(); if (N) { - Out << ' '; + if (N > 2) { + Indent += std::string(IndentSize, ' '); + Out << Indent; + } else { + Out << ' '; + } printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(0), @@ -492,11 +499,13 @@ for (unsigned i = 1; i < N; i++) { Out << ", "; + if (N > 2) Out << Indent; printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(i), PrintName, TypeTable, Machine); } + if (N > 2) Indent.resize(Indent.size() - IndentSize); } Out << " }"; From jlaskey at apple.com Mon Feb 27 06:43:42 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 06:43:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200602271243.GAA07717@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.30 -> 1.31 --- Log message: Re-orging file. --- Diffs of the changes: (+374 -573) DwarfWriter.cpp | 947 ++++++++++++++++++++++---------------------------------- 1 files changed, 374 insertions(+), 573 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.30 llvm/lib/CodeGen/DwarfWriter.cpp:1.31 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.30 Fri Feb 24 10:46:40 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Mon Feb 27 06:43:29 2006 @@ -26,563 +26,338 @@ #include using namespace llvm; +using namespace dwarf; static cl::opt DwarfVerbose("dwarf-verbose", cl::Hidden, cl::desc("Add comments to Dwarf directives.")); +namespace llvm { + //===----------------------------------------------------------------------===// +// Forward declarations. +// +class CompileUnit; +class DIE; -/// TagString - Return the string for the specified tag. -/// -static const char *TagString(unsigned Tag) { - switch(Tag) { - case DW_TAG_array_type: return "TAG_array_type"; - case DW_TAG_class_type: return "TAG_class_type"; - case DW_TAG_entry_point: return "TAG_entry_point"; - case DW_TAG_enumeration_type: return "TAG_enumeration_type"; - case DW_TAG_formal_parameter: return "TAG_formal_parameter"; - case DW_TAG_imported_declaration: return "TAG_imported_declaration"; - case DW_TAG_label: return "TAG_label"; - case DW_TAG_lexical_block: return "TAG_lexical_block"; - case DW_TAG_member: return "TAG_member"; - case DW_TAG_pointer_type: return "TAG_pointer_type"; - case DW_TAG_reference_type: return "TAG_reference_type"; - case DW_TAG_compile_unit: return "TAG_compile_unit"; - case DW_TAG_string_type: return "TAG_string_type"; - case DW_TAG_structure_type: return "TAG_structure_type"; - case DW_TAG_subroutine_type: return "TAG_subroutine_type"; - case DW_TAG_typedef: return "TAG_typedef"; - case DW_TAG_union_type: return "TAG_union_type"; - case DW_TAG_unspecified_parameters: return "TAG_unspecified_parameters"; - case DW_TAG_variant: return "TAG_variant"; - case DW_TAG_common_block: return "TAG_common_block"; - case DW_TAG_common_inclusion: return "TAG_common_inclusion"; - case DW_TAG_inheritance: return "TAG_inheritance"; - case DW_TAG_inlined_subroutine: return "TAG_inlined_subroutine"; - case DW_TAG_module: return "TAG_module"; - case DW_TAG_ptr_to_member_type: return "TAG_ptr_to_member_type"; - case DW_TAG_set_type: return "TAG_set_type"; - case DW_TAG_subrange_type: return "TAG_subrange_type"; - case DW_TAG_with_stmt: return "TAG_with_stmt"; - case DW_TAG_access_declaration: return "TAG_access_declaration"; - case DW_TAG_base_type: return "TAG_base_type"; - case DW_TAG_catch_block: return "TAG_catch_block"; - case DW_TAG_const_type: return "TAG_const_type"; - case DW_TAG_constant: return "TAG_constant"; - case DW_TAG_enumerator: return "TAG_enumerator"; - case DW_TAG_file_type: return "TAG_file_type"; - case DW_TAG_friend: return "TAG_friend"; - case DW_TAG_namelist: return "TAG_namelist"; - case DW_TAG_namelist_item: return "TAG_namelist_item"; - case DW_TAG_packed_type: return "TAG_packed_type"; - case DW_TAG_subprogram: return "TAG_subprogram"; - case DW_TAG_template_type_parameter: return "TAG_template_type_parameter"; - case DW_TAG_template_value_parameter: return "TAG_template_value_parameter"; - case DW_TAG_thrown_type: return "TAG_thrown_type"; - case DW_TAG_try_block: return "TAG_try_block"; - case DW_TAG_variant_part: return "TAG_variant_part"; - case DW_TAG_variable: return "TAG_variable"; - case DW_TAG_volatile_type: return "TAG_volatile_type"; - case DW_TAG_dwarf_procedure: return "TAG_dwarf_procedure"; - case DW_TAG_restrict_type: return "TAG_restrict_type"; - case DW_TAG_interface_type: return "TAG_interface_type"; - case DW_TAG_namespace: return "TAG_namespace"; - case DW_TAG_imported_module: return "TAG_imported_module"; - case DW_TAG_unspecified_type: return "TAG_unspecified_type"; - case DW_TAG_partial_unit: return "TAG_partial_unit"; - case DW_TAG_imported_unit: return "TAG_imported_unit"; - case DW_TAG_condition: return "TAG_condition"; - case DW_TAG_shared_type: return "TAG_shared_type"; - case DW_TAG_lo_user: return "TAG_lo_user"; - case DW_TAG_hi_user: return "TAG_hi_user"; - } - assert(0 && "Unknown Dwarf Tag"); - return ""; -} - -/// ChildrenString - Return the string for the specified children flag. -/// -static const char *ChildrenString(unsigned Children) { - switch(Children) { - case DW_CHILDREN_no: return "CHILDREN_no"; - case DW_CHILDREN_yes: return "CHILDREN_yes"; - } - assert(0 && "Unknown Dwarf ChildrenFlag"); - return ""; -} - -/// AttributeString - Return the string for the specified attribute. -/// -static const char *AttributeString(unsigned Attribute) { - switch(Attribute) { - case DW_AT_sibling: return "AT_sibling"; - case DW_AT_location: return "AT_location"; - case DW_AT_name: return "AT_name"; - case DW_AT_ordering: return "AT_ordering"; - case DW_AT_byte_size: return "AT_byte_size"; - case DW_AT_bit_offset: return "AT_bit_offset"; - case DW_AT_bit_size: return "AT_bit_size"; - case DW_AT_stmt_list: return "AT_stmt_list"; - case DW_AT_low_pc: return "AT_low_pc"; - case DW_AT_high_pc: return "AT_high_pc"; - case DW_AT_language: return "AT_language"; - case DW_AT_discr: return "AT_discr"; - case DW_AT_discr_value: return "AT_discr_value"; - case DW_AT_visibility: return "AT_visibility"; - case DW_AT_import: return "AT_import"; - case DW_AT_string_length: return "AT_string_length"; - case DW_AT_common_reference: return "AT_common_reference"; - case DW_AT_comp_dir: return "AT_comp_dir"; - case DW_AT_const_value: return "AT_const_value"; - case DW_AT_containing_type: return "AT_containing_type"; - case DW_AT_default_value: return "AT_default_value"; - case DW_AT_inline: return "AT_inline"; - case DW_AT_is_optional: return "AT_is_optional"; - case DW_AT_lower_bound: return "AT_lower_bound"; - case DW_AT_producer: return "AT_producer"; - case DW_AT_prototyped: return "AT_prototyped"; - case DW_AT_return_addr: return "AT_return_addr"; - case DW_AT_start_scope: return "AT_start_scope"; - case DW_AT_bit_stride: return "AT_bit_stride"; - case DW_AT_upper_bound: return "AT_upper_bound"; - case DW_AT_abstract_origin: return "AT_abstract_origin"; - case DW_AT_accessibility: return "AT_accessibility"; - case DW_AT_address_class: return "AT_address_class"; - case DW_AT_artificial: return "AT_artificial"; - case DW_AT_base_types: return "AT_base_types"; - case DW_AT_calling_convention: return "AT_calling_convention"; - case DW_AT_count: return "AT_count"; - case DW_AT_data_member_location: return "AT_data_member_location"; - case DW_AT_decl_column: return "AT_decl_column"; - case DW_AT_decl_file: return "AT_decl_file"; - case DW_AT_decl_line: return "AT_decl_line"; - case DW_AT_declaration: return "AT_declaration"; - case DW_AT_discr_list: return "AT_discr_list"; - case DW_AT_encoding: return "AT_encoding"; - case DW_AT_external: return "AT_external"; - case DW_AT_frame_base: return "AT_frame_base"; - case DW_AT_friend: return "AT_friend"; - case DW_AT_identifier_case: return "AT_identifier_case"; - case DW_AT_macro_info: return "AT_macro_info"; - case DW_AT_namelist_item: return "AT_namelist_item"; - case DW_AT_priority: return "AT_priority"; - case DW_AT_segment: return "AT_segment"; - case DW_AT_specification: return "AT_specification"; - case DW_AT_static_link: return "AT_static_link"; - case DW_AT_type: return "AT_type"; - case DW_AT_use_location: return "AT_use_location"; - case DW_AT_variable_parameter: return "AT_variable_parameter"; - case DW_AT_virtuality: return "AT_virtuality"; - case DW_AT_vtable_elem_location: return "AT_vtable_elem_location"; - case DW_AT_allocated: return "AT_allocated"; - case DW_AT_associated: return "AT_associated"; - case DW_AT_data_location: return "AT_data_location"; - case DW_AT_byte_stride: return "AT_byte_stride"; - case DW_AT_entry_pc: return "AT_entry_pc"; - case DW_AT_use_UTF8: return "AT_use_UTF8"; - case DW_AT_extension: return "AT_extension"; - case DW_AT_ranges: return "AT_ranges"; - case DW_AT_trampoline: return "AT_trampoline"; - case DW_AT_call_column: return "AT_call_column"; - case DW_AT_call_file: return "AT_call_file"; - case DW_AT_call_line: return "AT_call_line"; - case DW_AT_description: return "AT_description"; - case DW_AT_binary_scale: return "AT_binary_scale"; - case DW_AT_decimal_scale: return "AT_decimal_scale"; - case DW_AT_small: return "AT_small"; - case DW_AT_decimal_sign: return "AT_decimal_sign"; - case DW_AT_digit_count: return "AT_digit_count"; - case DW_AT_picture_string: return "AT_picture_string"; - case DW_AT_mutable: return "AT_mutable"; - case DW_AT_threads_scaled: return "AT_threads_scaled"; - case DW_AT_explicit: return "AT_explicit"; - case DW_AT_object_pointer: return "AT_object_pointer"; - case DW_AT_endianity: return "AT_endianity"; - case DW_AT_elemental: return "AT_elemental"; - case DW_AT_pure: return "AT_pure"; - case DW_AT_recursive: return "AT_recursive"; - case DW_AT_lo_user: return "AT_lo_user"; - case DW_AT_hi_user: return "AT_hi_user"; - } - assert(0 && "Unknown Dwarf Attribute"); - return ""; -} - -/// FormEncodingString - Return the string for the specified form encoding. -/// -static const char *FormEncodingString(unsigned Encoding) { - switch(Encoding) { - case DW_FORM_addr: return "FORM_addr"; - case DW_FORM_block2: return "FORM_block2"; - case DW_FORM_block4: return "FORM_block4"; - case DW_FORM_data2: return "FORM_data2"; - case DW_FORM_data4: return "FORM_data4"; - case DW_FORM_data8: return "FORM_data8"; - case DW_FORM_string: return "FORM_string"; - case DW_FORM_block: return "FORM_block"; - case DW_FORM_block1: return "FORM_block1"; - case DW_FORM_data1: return "FORM_data1"; - case DW_FORM_flag: return "FORM_flag"; - case DW_FORM_sdata: return "FORM_sdata"; - case DW_FORM_strp: return "FORM_strp"; - case DW_FORM_udata: return "FORM_udata"; - case DW_FORM_ref_addr: return "FORM_ref_addr"; - case DW_FORM_ref1: return "FORM_ref1"; - case DW_FORM_ref2: return "FORM_ref2"; - case DW_FORM_ref4: return "FORM_ref4"; - case DW_FORM_ref8: return "FORM_ref8"; - case DW_FORM_ref_udata: return "FORM_ref_udata"; - case DW_FORM_indirect: return "FORM_indirect"; - } - assert(0 && "Unknown Dwarf Form Encoding"); - return ""; -} - -/// OperationEncodingString - Return the string for the specified operation -/// encoding. -static const char *OperationEncodingString(unsigned Encoding) { - switch(Encoding) { - case DW_OP_addr: return "OP_addr"; - case DW_OP_deref: return "OP_deref"; - case DW_OP_const1u: return "OP_const1u"; - case DW_OP_const1s: return "OP_const1s"; - case DW_OP_const2u: return "OP_const2u"; - case DW_OP_const2s: return "OP_const2s"; - case DW_OP_const4u: return "OP_const4u"; - case DW_OP_const4s: return "OP_const4s"; - case DW_OP_const8u: return "OP_const8u"; - case DW_OP_const8s: return "OP_const8s"; - case DW_OP_constu: return "OP_constu"; - case DW_OP_consts: return "OP_consts"; - case DW_OP_dup: return "OP_dup"; - case DW_OP_drop: return "OP_drop"; - case DW_OP_over: return "OP_over"; - case DW_OP_pick: return "OP_pick"; - case DW_OP_swap: return "OP_swap"; - case DW_OP_rot: return "OP_rot"; - case DW_OP_xderef: return "OP_xderef"; - case DW_OP_abs: return "OP_abs"; - case DW_OP_and: return "OP_and"; - case DW_OP_div: return "OP_div"; - case DW_OP_minus: return "OP_minus"; - case DW_OP_mod: return "OP_mod"; - case DW_OP_mul: return "OP_mul"; - case DW_OP_neg: return "OP_neg"; - case DW_OP_not: return "OP_not"; - case DW_OP_or: return "OP_or"; - case DW_OP_plus: return "OP_plus"; - case DW_OP_plus_uconst: return "OP_plus_uconst"; - case DW_OP_shl: return "OP_shl"; - case DW_OP_shr: return "OP_shr"; - case DW_OP_shra: return "OP_shra"; - case DW_OP_xor: return "OP_xor"; - case DW_OP_skip: return "OP_skip"; - case DW_OP_bra: return "OP_bra"; - case DW_OP_eq: return "OP_eq"; - case DW_OP_ge: return "OP_ge"; - case DW_OP_gt: return "OP_gt"; - case DW_OP_le: return "OP_le"; - case DW_OP_lt: return "OP_lt"; - case DW_OP_ne: return "OP_ne"; - case DW_OP_lit0: return "OP_lit0"; - case DW_OP_lit1: return "OP_lit1"; - case DW_OP_lit31: return "OP_lit31"; - case DW_OP_reg0: return "OP_reg0"; - case DW_OP_reg1: return "OP_reg1"; - case DW_OP_reg31: return "OP_reg31"; - case DW_OP_breg0: return "OP_breg0"; - case DW_OP_breg1: return "OP_breg1"; - case DW_OP_breg31: return "OP_breg31"; - case DW_OP_regx: return "OP_regx"; - case DW_OP_fbreg: return "OP_fbreg"; - case DW_OP_bregx: return "OP_bregx"; - case DW_OP_piece: return "OP_piece"; - case DW_OP_deref_size: return "OP_deref_size"; - case DW_OP_xderef_size: return "OP_xderef_size"; - case DW_OP_nop: return "OP_nop"; - case DW_OP_push_object_address: return "OP_push_object_address"; - case DW_OP_call2: return "OP_call2"; - case DW_OP_call4: return "OP_call4"; - case DW_OP_call_ref: return "OP_call_ref"; - case DW_OP_form_tls_address: return "OP_form_tls_address"; - case DW_OP_call_frame_cfa: return "OP_call_frame_cfa"; - case DW_OP_lo_user: return "OP_lo_user"; - case DW_OP_hi_user: return "OP_hi_user"; - } - assert(0 && "Unknown Dwarf Operation Encoding"); - return ""; -} - -/// AttributeEncodingString - Return the string for the specified attribute -/// encoding. -static const char *AttributeEncodingString(unsigned Encoding) { - switch(Encoding) { - case DW_ATE_address: return "ATE_address"; - case DW_ATE_boolean: return "ATE_boolean"; - case DW_ATE_complex_float: return "ATE_complex_float"; - case DW_ATE_float: return "ATE_float"; - case DW_ATE_signed: return "ATE_signed"; - case DW_ATE_signed_char: return "ATE_signed_char"; - case DW_ATE_unsigned: return "ATE_unsigned"; - case DW_ATE_unsigned_char: return "ATE_unsigned_char"; - case DW_ATE_imaginary_float: return "ATE_imaginary_float"; - case DW_ATE_packed_decimal: return "ATE_packed_decimal"; - case DW_ATE_numeric_string: return "ATE_numeric_string"; - case DW_ATE_edited: return "ATE_edited"; - case DW_ATE_signed_fixed: return "ATE_signed_fixed"; - case DW_ATE_unsigned_fixed: return "ATE_unsigned_fixed"; - case DW_ATE_decimal_float: return "ATE_decimal_float"; - case DW_ATE_lo_user: return "ATE_lo_user"; - case DW_ATE_hi_user: return "ATE_hi_user"; - } - assert(0 && "Unknown Dwarf Attribute Encoding"); - return ""; -} - -/// DecimalSignString - Return the string for the specified decimal sign -/// attribute. -static const char *DecimalSignString(unsigned Sign) { - switch(Sign) { - case DW_DS_unsigned: return "DS_unsigned"; - case DW_DS_leading_overpunch: return "DS_leading_overpunch"; - case DW_DS_trailing_overpunch: return "DS_trailing_overpunch"; - case DW_DS_leading_separate: return "DS_leading_separate"; - case DW_DS_trailing_separate: return "DS_trailing_separate"; - } - assert(0 && "Unknown Dwarf Decimal Sign Attribute"); - return ""; -} - -/// EndianityString - Return the string for the specified endianity. -/// -static const char *EndianityString(unsigned Endian) { - switch(Endian) { - case DW_END_default: return "END_default"; - case DW_END_big: return "END_big"; - case DW_END_little: return "END_little"; - case DW_END_lo_user: return "END_lo_user"; - case DW_END_hi_user: return "END_hi_user"; - } - assert(0 && "Unknown Dwarf Endianity"); - return ""; -} - -/// AccessibilityString - Return the string for the specified accessibility. -/// -static const char *AccessibilityString(unsigned Access) { - switch(Access) { - // Accessibility codes - case DW_ACCESS_public: return "ACCESS_public"; - case DW_ACCESS_protected: return "ACCESS_protected"; - case DW_ACCESS_private: return "ACCESS_private"; - } - assert(0 && "Unknown Dwarf Accessibility"); - return ""; -} - -/// VisibilityString - Return the string for the specified visibility. -/// -static const char *VisibilityString(unsigned Visibility) { - switch(Visibility) { - case DW_VIS_local: return "VIS_local"; - case DW_VIS_exported: return "VIS_exported"; - case DW_VIS_qualified: return "VIS_qualified"; - } - assert(0 && "Unknown Dwarf Visibility"); - return ""; -} - -/// VirtualityString - Return the string for the specified virtuality. -/// -static const char *VirtualityString(unsigned Virtuality) { - switch(Virtuality) { - case DW_VIRTUALITY_none: return "VIRTUALITY_none"; - case DW_VIRTUALITY_virtual: return "VIRTUALITY_virtual"; - case DW_VIRTUALITY_pure_virtual: return "VIRTUALITY_pure_virtual"; - } - assert(0 && "Unknown Dwarf Virtuality"); - return ""; -} - -/// LanguageString - Return the string for the specified language. -/// -static const char *LanguageString(unsigned Language) { - switch(Language) { - case DW_LANG_C89: return "LANG_C89"; - case DW_LANG_C: return "LANG_C"; - case DW_LANG_Ada83: return "LANG_Ada83"; - case DW_LANG_C_plus_plus: return "LANG_C_plus_plus"; - case DW_LANG_Cobol74: return "LANG_Cobol74"; - case DW_LANG_Cobol85: return "LANG_Cobol85"; - case DW_LANG_Fortran77: return "LANG_Fortran77"; - case DW_LANG_Fortran90: return "LANG_Fortran90"; - case DW_LANG_Pascal83: return "LANG_Pascal83"; - case DW_LANG_Modula2: return "LANG_Modula2"; - case DW_LANG_Java: return "LANG_Java"; - case DW_LANG_C99: return "LANG_C99"; - case DW_LANG_Ada95: return "LANG_Ada95"; - case DW_LANG_Fortran95: return "LANG_Fortran95"; - case DW_LANG_PLI: return "LANG_PLI"; - case DW_LANG_ObjC: return "LANG_ObjC"; - case DW_LANG_ObjC_plus_plus: return "LANG_ObjC_plus_plus"; - case DW_LANG_UPC: return "LANG_UPC"; - case DW_LANG_D: return "LANG_D"; - case DW_LANG_lo_user: return "LANG_lo_user"; - case DW_LANG_hi_user: return "LANG_hi_user"; - } - assert(0 && "Unknown Dwarf Language"); - return ""; -} - -/// CaseString - Return the string for the specified identifier case. -/// -static const char *CaseString(unsigned Case) { - switch(Case) { - case DW_ID_case_sensitive: return "ID_case_sensitive"; - case DW_ID_up_case: return "ID_up_case"; - case DW_ID_down_case: return "ID_down_case"; - case DW_ID_case_insensitive: return "ID_case_insensitive"; - } - assert(0 && "Unknown Dwarf Identifier Case"); - return ""; -} - -/// ConventionString - Return the string for the specified calling convention. -/// -static const char *ConventionString(unsigned Convention) { - switch(Convention) { - case DW_CC_normal: return "CC_normal"; - case DW_CC_program: return "CC_program"; - case DW_CC_nocall: return "CC_nocall"; - case DW_CC_lo_user: return "CC_lo_user"; - case DW_CC_hi_user: return "CC_hi_user"; - } - assert(0 && "Unknown Dwarf Calling Convention"); - return ""; -} - -/// InlineCodeString - Return the string for the specified inline code. -/// -static const char *InlineCodeString(unsigned Code) { - switch(Code) { - case DW_INL_not_inlined: return "INL_not_inlined"; - case DW_INL_inlined: return "INL_inlined"; - case DW_INL_declared_not_inlined: return "INL_declared_not_inlined"; - case DW_INL_declared_inlined: return "INL_declared_inlined"; - } - assert(0 && "Unknown Dwarf Inline Code"); - return ""; -} - -/// ArrayOrderString - Return the string for the specified array order. -/// -static const char *ArrayOrderString(unsigned Order) { - switch(Order) { - case DW_ORD_row_major: return "ORD_row_major"; - case DW_ORD_col_major: return "ORD_col_major"; - } - assert(0 && "Unknown Dwarf Array Order"); - return ""; -} - -/// DiscriminantString - Return the string for the specified discriminant -/// descriptor. -static const char *DiscriminantString(unsigned Discriminant) { - switch(Discriminant) { - case DW_DSC_label: return "DSC_label"; - case DW_DSC_range: return "DSC_range"; - } - assert(0 && "Unknown Dwarf Discriminant Descriptor"); - return ""; -} - -/// LNStandardString - Return the string for the specified line number standard. -/// -static const char *LNStandardString(unsigned Standard) { - switch(Standard) { - case DW_LNS_copy: return "LNS_copy"; - case DW_LNS_advance_pc: return "LNS_advance_pc"; - case DW_LNS_advance_line: return "LNS_advance_line"; - case DW_LNS_set_file: return "LNS_set_file"; - case DW_LNS_set_column: return "LNS_set_column"; - case DW_LNS_negate_stmt: return "LNS_negate_stmt"; - case DW_LNS_set_basic_block: return "LNS_set_basic_block"; - case DW_LNS_const_add_pc: return "LNS_const_add_pc"; - case DW_LNS_fixed_advance_pc: return "LNS_fixed_advance_pc"; - case DW_LNS_set_prologue_end: return "LNS_set_prologue_end"; - case DW_LNS_set_epilogue_begin: return "LNS_set_epilogue_begin"; - case DW_LNS_set_isa: return "LNS_set_isa"; - } - assert(0 && "Unknown Dwarf Line Number Standard"); - return ""; -} - -/// LNExtendedString - Return the string for the specified line number extended -/// opcode encodings. -static const char *LNExtendedString(unsigned Encoding) { - switch(Encoding) { - // Line Number Extended Opcode Encodings - case DW_LNE_end_sequence: return "LNE_end_sequence"; - case DW_LNE_set_address: return "LNE_set_address"; - case DW_LNE_define_file: return "LNE_define_file"; - case DW_LNE_lo_user: return "LNE_lo_user"; - case DW_LNE_hi_user: return "LNE_hi_user"; - } - assert(0 && "Unknown Dwarf Line Number Extended Opcode Encoding"); - return ""; -} - -/// MacinfoString - Return the string for the specified macinfo type encodings. -/// -static const char *MacinfoString(unsigned Encoding) { - switch(Encoding) { - // Macinfo Type Encodings - case DW_MACINFO_define: return "MACINFO_define"; - case DW_MACINFO_undef: return "MACINFO_undef"; - case DW_MACINFO_start_file: return "MACINFO_start_file"; - case DW_MACINFO_end_file: return "MACINFO_end_file"; - case DW_MACINFO_vendor_ext: return "MACINFO_vendor_ext"; - } - assert(0 && "Unknown Dwarf Macinfo Type Encodings"); - return ""; -} - -/// CallFrameString - Return the string for the specified call frame instruction -/// encodings. -static const char *CallFrameString(unsigned Encoding) { - switch(Encoding) { - case DW_CFA_advance_loc: return "CFA_advance_loc"; - case DW_CFA_offset: return "CFA_offset"; - case DW_CFA_restore: return "CFA_restore"; - case DW_CFA_set_loc: return "CFA_set_loc"; - case DW_CFA_advance_loc1: return "CFA_advance_loc1"; - case DW_CFA_advance_loc2: return "CFA_advance_loc2"; - case DW_CFA_advance_loc4: return "CFA_advance_loc4"; - case DW_CFA_offset_extended: return "CFA_offset_extended"; - case DW_CFA_restore_extended: return "CFA_restore_extended"; - case DW_CFA_undefined: return "CFA_undefined"; - case DW_CFA_same_value: return "CFA_same_value"; - case DW_CFA_register: return "CFA_register"; - case DW_CFA_remember_state: return "CFA_remember_state"; - case DW_CFA_restore_state: return "CFA_restore_state"; - case DW_CFA_def_cfa: return "CFA_def_cfa"; - case DW_CFA_def_cfa_register: return "CFA_def_cfa_register"; - case DW_CFA_def_cfa_offset: return "CFA_def_cfa_offset"; - case DW_CFA_def_cfa_expression: return "CFA_def_cfa_expression"; - case DW_CFA_expression: return "CFA_expression"; - case DW_CFA_offset_extended_sf: return "CFA_offset_extended_sf"; - case DW_CFA_def_cfa_sf: return "CFA_def_cfa_sf"; - case DW_CFA_def_cfa_offset_sf: return "CFA_def_cfa_offset_sf"; - case DW_CFA_val_offset: return "CFA_val_offset"; - case DW_CFA_val_offset_sf: return "CFA_val_offset_sf"; - case DW_CFA_val_expression: return "CFA_val_expression"; - case DW_CFA_lo_user: return "CFA_lo_user"; - case DW_CFA_hi_user: return "CFA_hi_user"; +//===----------------------------------------------------------------------===// +// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a +// Dwarf abbreviation. +class DIEAbbrevData { +private: + unsigned Attribute; // Dwarf attribute code. + unsigned Form; // Dwarf form code. + +public: + DIEAbbrevData(unsigned A, unsigned F) + : Attribute(A) + , Form(F) + {} + + // Accessors + unsigned getAttribute() const { return Attribute; } + unsigned getForm() const { return Form; } + + /// operator== - Used by DIEAbbrev to locate entry. + /// + bool operator==(const DIEAbbrevData &DAD) const { + return Attribute == DAD.Attribute && Form == DAD.Form; + } + + /// operator!= - Used by DIEAbbrev to locate entry. + /// + bool operator!=(const DIEAbbrevData &DAD) const { + return Attribute != DAD.Attribute || Form != DAD.Form; + } + + /// operator< - Used by DIEAbbrev to locate entry. + /// + bool operator<(const DIEAbbrevData &DAD) const { + return Attribute < DAD.Attribute || + (Attribute == DAD.Attribute && Form < DAD.Form); } - assert(0 && "Unknown Dwarf Call Frame Instruction Encodings"); - return ""; -} +}; + +//===----------------------------------------------------------------------===// +// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug +// information object. +class DIEAbbrev { +private: + unsigned Tag; // Dwarf tag code. + unsigned ChildrenFlag; // Dwarf children flag. + std::vector Data; // Raw data bytes for abbreviation. + +public: + + DIEAbbrev(unsigned T, unsigned C) + : Tag(T) + , ChildrenFlag(C) + , Data() + {} + ~DIEAbbrev() {} + + // Accessors + unsigned getTag() const { return Tag; } + unsigned getChildrenFlag() const { return ChildrenFlag; } + const std::vector &getData() const { return Data; } + void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; } + + /// operator== - Used by UniqueVector to locate entry. + /// + bool operator==(const DIEAbbrev &DA) const; + + /// operator< - Used by UniqueVector to locate entry. + /// + bool operator<(const DIEAbbrev &DA) const; + + /// AddAttribute - Adds another set of attribute information to the + /// abbreviation. + void AddAttribute(unsigned Attribute, unsigned Form) { + Data.push_back(DIEAbbrevData(Attribute, Form)); + } + + /// Emit - Print the abbreviation using the specified Dwarf writer. + /// + void Emit(const DwarfWriter &DW) const; + +#ifndef NDEBUG + void print(std::ostream &O); + void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +// DIEValue - A debug information entry value. +// +class DIEValue { +public: + enum { + isInteger, + isString, + isLabel, + isAsIsLabel, + isDelta, + isEntry + }; + + unsigned Type; // Type of the value + + DIEValue(unsigned T) : Type(T) {} + virtual ~DIEValue() {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEValue *) { return true; } + + /// EmitValue - Emit value via the Dwarf writer. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const = 0; + + /// SizeOf - Return the size of a value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const = 0; +}; + +//===----------------------------------------------------------------------===// +// DWInteger - An integer value DIE. +// +class DIEInteger : public DIEValue { +private: + uint64_t Integer; + +public: + DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEInteger *) { return true; } + static bool classof(const DIEValue *I) { return I->Type == isInteger; } + + /// EmitValue - Emit integer of appropriate size. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of integer value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; +}; + +//===----------------------------------------------------------------------===// +// DIEString - A string value DIE. +// +struct DIEString : public DIEValue { + const std::string String; + + DIEString(const std::string &S) : DIEValue(isString), String(S) {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEString *) { return true; } + static bool classof(const DIEValue *S) { return S->Type == isString; } + + /// EmitValue - Emit string value. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of string value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; +}; + +//===----------------------------------------------------------------------===// +// DIEDwarfLabel - A Dwarf internal label expression DIE. +// +struct DIEDwarfLabel : public DIEValue { + const DWLabel Label; + + DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEDwarfLabel *) { return true; } + static bool classof(const DIEValue *L) { return L->Type == isLabel; } + + /// EmitValue - Emit label value. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of label value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; +}; + + +//===----------------------------------------------------------------------===// +// DIEObjectLabel - A label to an object in code or data. +// +struct DIEObjectLabel : public DIEValue { + const std::string Label; + + DIEObjectLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEObjectLabel *) { return true; } + static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; } + + /// EmitValue - Emit label value. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of label value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; +}; + +//===----------------------------------------------------------------------===// +// DIEDelta - A simple label difference DIE. +// +struct DIEDelta : public DIEValue { + const DWLabel LabelHi; + const DWLabel LabelLo; + + DIEDelta(const DWLabel &Hi, const DWLabel &Lo) + : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEDelta *) { return true; } + static bool classof(const DIEValue *D) { return D->Type == isDelta; } + + /// EmitValue - Emit delta value. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of delta value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; +}; + +//===----------------------------------------------------------------------===// +// DIEntry - A pointer to a debug information entry. +// +struct DIEntry : public DIEValue { + DIE *Entry; + + DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} + + // Implement isa/cast/dyncast. + static bool classof(const DIEntry *) { return true; } + static bool classof(const DIEValue *E) { return E->Type == isEntry; } + + /// EmitValue - Emit delta value. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of delta value in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; +}; + +//===----------------------------------------------------------------------===// +// DIE - A structured debug information entry. Has an abbreviation which +// describes it's organization. +class DIE { +private: + DIEAbbrev *Abbrev; // Temporary buffer for abbreviation. + unsigned AbbrevID; // Decribing abbreviation ID. + unsigned Offset; // Offset in debug info section. + unsigned Size; // Size of instance + children. + std::vector Children; // Children DIEs. + std::vector Values; // Attributes values. + +public: + DIE(unsigned Tag); + ~DIE(); + + // Accessors + unsigned getAbbrevID() const { return AbbrevID; } + unsigned getOffset() const { return Offset; } + unsigned getSize() const { return Size; } + const std::vector &getChildren() const { return Children; } + const std::vector &getValues() const { return Values; } + void setOffset(unsigned O) { Offset = O; } + void setSize(unsigned S) { Size = S; } + + /// SiblingOffset - Return the offset of the debug information entry's + /// sibling. + unsigned SiblingOffset() const { return Offset + Size; } + + /// AddUInt - Add an unsigned integer attribute data and value. + /// + void AddUInt(unsigned Attribute, unsigned Form, uint64_t Integer); + + /// AddSInt - Add an signed integer attribute data and value. + /// + void AddSInt(unsigned Attribute, unsigned Form, int64_t Integer); + + /// AddString - Add a std::string attribute data and value. + /// + void AddString(unsigned Attribute, unsigned Form, + const std::string &String); + + /// AddLabel - Add a Dwarf label attribute data and value. + /// + void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label); + + /// AddObjectLabel - Add a non-Dwarf label attribute data and value. + /// + void AddObjectLabel(unsigned Attribute, unsigned Form, + const std::string &Label); + + /// AddDelta - Add a label delta attribute data and value. + /// + void AddDelta(unsigned Attribute, unsigned Form, + const DWLabel &Hi, const DWLabel &Lo); + + /// AddDIEntry - Add a DIE attribute data and value. + /// + void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry); + + /// Complete - Indicate that all attributes have been added and + /// ready to get an abbreviation ID. + /// + void Complete(DwarfWriter &DW); + + /// AddChild - Add a child to the DIE. + void AddChild(DIE *Child); +}; + +} // End of namespace llvm //===----------------------------------------------------------------------===// @@ -1442,14 +1217,16 @@ // Get the abbreviation for this DIE. unsigned AbbrevID = Die->getAbbrevID(); const DIEAbbrev &Abbrev = Abbreviations[AbbrevID]; + + O << "\n"; // Emit the code (index) for the abbreviation. EmitULEB128Bytes(AbbrevID); EOL(std::string("Abbrev [" + utostr(AbbrevID) + - "] " + - TagString(Abbrev.getTag())) + - " "); + "] 0x" + utohexstr(Die->getOffset()) + + ":0x" + utohexstr(Die->getSize()) + " " + + TagString(Abbrev.getTag()))); const std::vector &Values = Die->getValues(); const std::vector &AbbrevData = Abbrev.getData(); @@ -1535,14 +1312,16 @@ /// SizeAndOffsets - Compute the size and offset of all the DIEs. /// void DwarfWriter::SizeAndOffsets() { - // Compute size of debug unit header - unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info - sizeof(int16_t) + // DWARF version number - sizeof(int32_t) + // Offset Into Abbrev. Section - sizeof(int8_t); // Pointer Size (in bytes) + unsigned Offset = 0; // Process each compile unit. for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { + // Compute size of compile unit header + Offset += sizeof(int32_t) + // Length of Compilation Unit Info + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + Offset = SizeAndOffsetDie(CompileUnits[i], Offset); } } @@ -1559,26 +1338,28 @@ // If there are any compile units. if (N) { EmitLabel("info_begin", 0); - - // Emit the compile units header. - - // Emit size of content not including length itself - unsigned ContentSize = CompileUnits[N - 1]->SiblingOffset(); - EmitInt32(ContentSize - sizeof(int32_t)); - EOL("Length of Compilation Unit Info"); - - EmitInt16(DWARF_VERSION); EOL("DWARF version number"); - EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section"); - - EmitInt8(AddressSize); EOL("Address Size (in bytes)"); - // Process each compile unit. for (unsigned i = 0; i < N; ++i) { + // Emit the compile units header. + + // Emit size of content not including length itself + unsigned ContentSize = CompileUnits[i]->getSize() + + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + + EmitInt32(ContentSize); EOL("Length of Compilation Unit Info"); + EmitInt16(DWARF_VERSION); EOL("DWARF version number"); + EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section"); + EmitInt8(AddressSize); EOL("Address Size (in bytes)"); + EmitDIE(CompileUnits[i]); } - + EmitLabel("info_end", 0); + + O << "\n"; } } @@ -1603,9 +1384,13 @@ // Emit the abbreviations data. Abbrev.Emit(*this); + + O << "\n"; } EmitLabel("abbrev_end", 0); + + O << "\n"; } } @@ -1748,6 +1533,8 @@ EmitInt8(1); O << "\n"; EmitLabel("line_end", 0); + + O << "\n"; } /// EmitDebugFrame - Emit visible names into a debug frame section. @@ -1789,6 +1576,8 @@ EmitInt32(0); EOL("End Mark"); EmitLabel("pubnames_end", 0); + + O << "\n"; } } @@ -1799,6 +1588,8 @@ if (!GlobalTypes.empty()) { // Start the dwarf pubtypes section. Asm->SwitchSection(DwarfPubTypesSection, 0); + + O << "\n"; } } @@ -1819,6 +1610,8 @@ const std::string &String = StringPool[StringID]; EmitString(String); O << "\n"; } + + O << "\n"; } } @@ -1827,6 +1620,8 @@ void DwarfWriter::EmitDebugLoc() { // Start the dwarf loc section. Asm->SwitchSection(DwarfLocSection, 0); + + O << "\n"; } /// EmitDebugARanges - Emit visible names into a debug aranges section. @@ -1857,6 +1652,8 @@ EmitInt32(0); EOL("EOM (1)"); EmitInt32(0); EOL("EOM (2)"); + + O << "\n"; } /// EmitDebugRanges - Emit visible names into a debug ranges section. @@ -1864,6 +1661,8 @@ void DwarfWriter::EmitDebugRanges() { // Start the dwarf ranges section. Asm->SwitchSection(DwarfRangesSection, 0); + + O << "\n"; } /// EmitDebugMacInfo - Emit visible names into a debug macinfo section. @@ -1871,6 +1670,8 @@ void DwarfWriter::EmitDebugMacInfo() { // Start the dwarf macinfo section. Asm->SwitchSection(DwarfMacInfoSection, 0); + + O << "\n"; } /// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and @@ -2006,13 +1807,13 @@ EmitDebugLines(); // Emit info into a debug frame section. - EmitDebugFrame(); + // EmitDebugFrame(); // Emit info into a debug pubnames section. EmitDebugPubNames(); // Emit info into a debug pubtypes section. - EmitDebugPubTypes(); + // EmitDebugPubTypes(); // Emit info into a debug str section. EmitDebugStr(); From jlaskey at apple.com Mon Feb 27 06:43:42 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 06:43:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/Dwarf.cpp Message-ID: <200602271243.GAA07721@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Dwarf.cpp added (r1.1) --- Log message: Re-orging file. --- Diffs of the changes: (+572 -0) Dwarf.cpp | 572 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 572 insertions(+) Index: llvm/lib/Support/Dwarf.cpp diff -c /dev/null llvm/lib/Support/Dwarf.cpp:1.1 *** /dev/null Mon Feb 27 06:43:39 2006 --- llvm/lib/Support/Dwarf.cpp Mon Feb 27 06:43:29 2006 *************** *** 0 **** --- 1,572 ---- + //===-- llvm/Support/Dwarf.cpp - Dwarf Framework ----------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by James M. Laskey and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains support for generic dwarf information. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Support/Dwarf.h" + + #include + + namespace dwarf { + + /// TagString - Return the string for the specified tag. + /// + const char *TagString(unsigned Tag) { + switch(Tag) { + case DW_TAG_array_type: return "TAG_array_type"; + case DW_TAG_class_type: return "TAG_class_type"; + case DW_TAG_entry_point: return "TAG_entry_point"; + case DW_TAG_enumeration_type: return "TAG_enumeration_type"; + case DW_TAG_formal_parameter: return "TAG_formal_parameter"; + case DW_TAG_imported_declaration: return "TAG_imported_declaration"; + case DW_TAG_label: return "TAG_label"; + case DW_TAG_lexical_block: return "TAG_lexical_block"; + case DW_TAG_member: return "TAG_member"; + case DW_TAG_pointer_type: return "TAG_pointer_type"; + case DW_TAG_reference_type: return "TAG_reference_type"; + case DW_TAG_compile_unit: return "TAG_compile_unit"; + case DW_TAG_string_type: return "TAG_string_type"; + case DW_TAG_structure_type: return "TAG_structure_type"; + case DW_TAG_subroutine_type: return "TAG_subroutine_type"; + case DW_TAG_typedef: return "TAG_typedef"; + case DW_TAG_union_type: return "TAG_union_type"; + case DW_TAG_unspecified_parameters: return "TAG_unspecified_parameters"; + case DW_TAG_variant: return "TAG_variant"; + case DW_TAG_common_block: return "TAG_common_block"; + case DW_TAG_common_inclusion: return "TAG_common_inclusion"; + case DW_TAG_inheritance: return "TAG_inheritance"; + case DW_TAG_inlined_subroutine: return "TAG_inlined_subroutine"; + case DW_TAG_module: return "TAG_module"; + case DW_TAG_ptr_to_member_type: return "TAG_ptr_to_member_type"; + case DW_TAG_set_type: return "TAG_set_type"; + case DW_TAG_subrange_type: return "TAG_subrange_type"; + case DW_TAG_with_stmt: return "TAG_with_stmt"; + case DW_TAG_access_declaration: return "TAG_access_declaration"; + case DW_TAG_base_type: return "TAG_base_type"; + case DW_TAG_catch_block: return "TAG_catch_block"; + case DW_TAG_const_type: return "TAG_const_type"; + case DW_TAG_constant: return "TAG_constant"; + case DW_TAG_enumerator: return "TAG_enumerator"; + case DW_TAG_file_type: return "TAG_file_type"; + case DW_TAG_friend: return "TAG_friend"; + case DW_TAG_namelist: return "TAG_namelist"; + case DW_TAG_namelist_item: return "TAG_namelist_item"; + case DW_TAG_packed_type: return "TAG_packed_type"; + case DW_TAG_subprogram: return "TAG_subprogram"; + case DW_TAG_template_type_parameter: return "TAG_template_type_parameter"; + case DW_TAG_template_value_parameter: return "TAG_template_value_parameter"; + case DW_TAG_thrown_type: return "TAG_thrown_type"; + case DW_TAG_try_block: return "TAG_try_block"; + case DW_TAG_variant_part: return "TAG_variant_part"; + case DW_TAG_variable: return "TAG_variable"; + case DW_TAG_volatile_type: return "TAG_volatile_type"; + case DW_TAG_dwarf_procedure: return "TAG_dwarf_procedure"; + case DW_TAG_restrict_type: return "TAG_restrict_type"; + case DW_TAG_interface_type: return "TAG_interface_type"; + case DW_TAG_namespace: return "TAG_namespace"; + case DW_TAG_imported_module: return "TAG_imported_module"; + case DW_TAG_unspecified_type: return "TAG_unspecified_type"; + case DW_TAG_partial_unit: return "TAG_partial_unit"; + case DW_TAG_imported_unit: return "TAG_imported_unit"; + case DW_TAG_condition: return "TAG_condition"; + case DW_TAG_shared_type: return "TAG_shared_type"; + case DW_TAG_lo_user: return "TAG_lo_user"; + case DW_TAG_hi_user: return "TAG_hi_user"; + } + assert(0 && "Unknown Dwarf Tag"); + return ""; + } + + /// ChildrenString - Return the string for the specified children flag. + /// + const char *ChildrenString(unsigned Children) { + switch(Children) { + case DW_CHILDREN_no: return "CHILDREN_no"; + case DW_CHILDREN_yes: return "CHILDREN_yes"; + } + assert(0 && "Unknown Dwarf ChildrenFlag"); + return ""; + } + + /// AttributeString - Return the string for the specified attribute. + /// + const char *AttributeString(unsigned Attribute) { + switch(Attribute) { + case DW_AT_sibling: return "AT_sibling"; + case DW_AT_location: return "AT_location"; + case DW_AT_name: return "AT_name"; + case DW_AT_ordering: return "AT_ordering"; + case DW_AT_byte_size: return "AT_byte_size"; + case DW_AT_bit_offset: return "AT_bit_offset"; + case DW_AT_bit_size: return "AT_bit_size"; + case DW_AT_stmt_list: return "AT_stmt_list"; + case DW_AT_low_pc: return "AT_low_pc"; + case DW_AT_high_pc: return "AT_high_pc"; + case DW_AT_language: return "AT_language"; + case DW_AT_discr: return "AT_discr"; + case DW_AT_discr_value: return "AT_discr_value"; + case DW_AT_visibility: return "AT_visibility"; + case DW_AT_import: return "AT_import"; + case DW_AT_string_length: return "AT_string_length"; + case DW_AT_common_reference: return "AT_common_reference"; + case DW_AT_comp_dir: return "AT_comp_dir"; + case DW_AT_const_value: return "AT_const_value"; + case DW_AT_containing_type: return "AT_containing_type"; + case DW_AT_default_value: return "AT_default_value"; + case DW_AT_inline: return "AT_inline"; + case DW_AT_is_optional: return "AT_is_optional"; + case DW_AT_lower_bound: return "AT_lower_bound"; + case DW_AT_producer: return "AT_producer"; + case DW_AT_prototyped: return "AT_prototyped"; + case DW_AT_return_addr: return "AT_return_addr"; + case DW_AT_start_scope: return "AT_start_scope"; + case DW_AT_bit_stride: return "AT_bit_stride"; + case DW_AT_upper_bound: return "AT_upper_bound"; + case DW_AT_abstract_origin: return "AT_abstract_origin"; + case DW_AT_accessibility: return "AT_accessibility"; + case DW_AT_address_class: return "AT_address_class"; + case DW_AT_artificial: return "AT_artificial"; + case DW_AT_base_types: return "AT_base_types"; + case DW_AT_calling_convention: return "AT_calling_convention"; + case DW_AT_count: return "AT_count"; + case DW_AT_data_member_location: return "AT_data_member_location"; + case DW_AT_decl_column: return "AT_decl_column"; + case DW_AT_decl_file: return "AT_decl_file"; + case DW_AT_decl_line: return "AT_decl_line"; + case DW_AT_declaration: return "AT_declaration"; + case DW_AT_discr_list: return "AT_discr_list"; + case DW_AT_encoding: return "AT_encoding"; + case DW_AT_external: return "AT_external"; + case DW_AT_frame_base: return "AT_frame_base"; + case DW_AT_friend: return "AT_friend"; + case DW_AT_identifier_case: return "AT_identifier_case"; + case DW_AT_macro_info: return "AT_macro_info"; + case DW_AT_namelist_item: return "AT_namelist_item"; + case DW_AT_priority: return "AT_priority"; + case DW_AT_segment: return "AT_segment"; + case DW_AT_specification: return "AT_specification"; + case DW_AT_static_link: return "AT_static_link"; + case DW_AT_type: return "AT_type"; + case DW_AT_use_location: return "AT_use_location"; + case DW_AT_variable_parameter: return "AT_variable_parameter"; + case DW_AT_virtuality: return "AT_virtuality"; + case DW_AT_vtable_elem_location: return "AT_vtable_elem_location"; + case DW_AT_allocated: return "AT_allocated"; + case DW_AT_associated: return "AT_associated"; + case DW_AT_data_location: return "AT_data_location"; + case DW_AT_byte_stride: return "AT_byte_stride"; + case DW_AT_entry_pc: return "AT_entry_pc"; + case DW_AT_use_UTF8: return "AT_use_UTF8"; + case DW_AT_extension: return "AT_extension"; + case DW_AT_ranges: return "AT_ranges"; + case DW_AT_trampoline: return "AT_trampoline"; + case DW_AT_call_column: return "AT_call_column"; + case DW_AT_call_file: return "AT_call_file"; + case DW_AT_call_line: return "AT_call_line"; + case DW_AT_description: return "AT_description"; + case DW_AT_binary_scale: return "AT_binary_scale"; + case DW_AT_decimal_scale: return "AT_decimal_scale"; + case DW_AT_small: return "AT_small"; + case DW_AT_decimal_sign: return "AT_decimal_sign"; + case DW_AT_digit_count: return "AT_digit_count"; + case DW_AT_picture_string: return "AT_picture_string"; + case DW_AT_mutable: return "AT_mutable"; + case DW_AT_threads_scaled: return "AT_threads_scaled"; + case DW_AT_explicit: return "AT_explicit"; + case DW_AT_object_pointer: return "AT_object_pointer"; + case DW_AT_endianity: return "AT_endianity"; + case DW_AT_elemental: return "AT_elemental"; + case DW_AT_pure: return "AT_pure"; + case DW_AT_recursive: return "AT_recursive"; + case DW_AT_lo_user: return "AT_lo_user"; + case DW_AT_hi_user: return "AT_hi_user"; + } + assert(0 && "Unknown Dwarf Attribute"); + return ""; + } + + /// FormEncodingString - Return the string for the specified form encoding. + /// + const char *FormEncodingString(unsigned Encoding) { + switch(Encoding) { + case DW_FORM_addr: return "FORM_addr"; + case DW_FORM_block2: return "FORM_block2"; + case DW_FORM_block4: return "FORM_block4"; + case DW_FORM_data2: return "FORM_data2"; + case DW_FORM_data4: return "FORM_data4"; + case DW_FORM_data8: return "FORM_data8"; + case DW_FORM_string: return "FORM_string"; + case DW_FORM_block: return "FORM_block"; + case DW_FORM_block1: return "FORM_block1"; + case DW_FORM_data1: return "FORM_data1"; + case DW_FORM_flag: return "FORM_flag"; + case DW_FORM_sdata: return "FORM_sdata"; + case DW_FORM_strp: return "FORM_strp"; + case DW_FORM_udata: return "FORM_udata"; + case DW_FORM_ref_addr: return "FORM_ref_addr"; + case DW_FORM_ref1: return "FORM_ref1"; + case DW_FORM_ref2: return "FORM_ref2"; + case DW_FORM_ref4: return "FORM_ref4"; + case DW_FORM_ref8: return "FORM_ref8"; + case DW_FORM_ref_udata: return "FORM_ref_udata"; + case DW_FORM_indirect: return "FORM_indirect"; + } + assert(0 && "Unknown Dwarf Form Encoding"); + return ""; + } + + /// OperationEncodingString - Return the string for the specified operation + /// encoding. + const char *OperationEncodingString(unsigned Encoding) { + switch(Encoding) { + case DW_OP_addr: return "OP_addr"; + case DW_OP_deref: return "OP_deref"; + case DW_OP_const1u: return "OP_const1u"; + case DW_OP_const1s: return "OP_const1s"; + case DW_OP_const2u: return "OP_const2u"; + case DW_OP_const2s: return "OP_const2s"; + case DW_OP_const4u: return "OP_const4u"; + case DW_OP_const4s: return "OP_const4s"; + case DW_OP_const8u: return "OP_const8u"; + case DW_OP_const8s: return "OP_const8s"; + case DW_OP_constu: return "OP_constu"; + case DW_OP_consts: return "OP_consts"; + case DW_OP_dup: return "OP_dup"; + case DW_OP_drop: return "OP_drop"; + case DW_OP_over: return "OP_over"; + case DW_OP_pick: return "OP_pick"; + case DW_OP_swap: return "OP_swap"; + case DW_OP_rot: return "OP_rot"; + case DW_OP_xderef: return "OP_xderef"; + case DW_OP_abs: return "OP_abs"; + case DW_OP_and: return "OP_and"; + case DW_OP_div: return "OP_div"; + case DW_OP_minus: return "OP_minus"; + case DW_OP_mod: return "OP_mod"; + case DW_OP_mul: return "OP_mul"; + case DW_OP_neg: return "OP_neg"; + case DW_OP_not: return "OP_not"; + case DW_OP_or: return "OP_or"; + case DW_OP_plus: return "OP_plus"; + case DW_OP_plus_uconst: return "OP_plus_uconst"; + case DW_OP_shl: return "OP_shl"; + case DW_OP_shr: return "OP_shr"; + case DW_OP_shra: return "OP_shra"; + case DW_OP_xor: return "OP_xor"; + case DW_OP_skip: return "OP_skip"; + case DW_OP_bra: return "OP_bra"; + case DW_OP_eq: return "OP_eq"; + case DW_OP_ge: return "OP_ge"; + case DW_OP_gt: return "OP_gt"; + case DW_OP_le: return "OP_le"; + case DW_OP_lt: return "OP_lt"; + case DW_OP_ne: return "OP_ne"; + case DW_OP_lit0: return "OP_lit0"; + case DW_OP_lit1: return "OP_lit1"; + case DW_OP_lit31: return "OP_lit31"; + case DW_OP_reg0: return "OP_reg0"; + case DW_OP_reg1: return "OP_reg1"; + case DW_OP_reg31: return "OP_reg31"; + case DW_OP_breg0: return "OP_breg0"; + case DW_OP_breg1: return "OP_breg1"; + case DW_OP_breg31: return "OP_breg31"; + case DW_OP_regx: return "OP_regx"; + case DW_OP_fbreg: return "OP_fbreg"; + case DW_OP_bregx: return "OP_bregx"; + case DW_OP_piece: return "OP_piece"; + case DW_OP_deref_size: return "OP_deref_size"; + case DW_OP_xderef_size: return "OP_xderef_size"; + case DW_OP_nop: return "OP_nop"; + case DW_OP_push_object_address: return "OP_push_object_address"; + case DW_OP_call2: return "OP_call2"; + case DW_OP_call4: return "OP_call4"; + case DW_OP_call_ref: return "OP_call_ref"; + case DW_OP_form_tls_address: return "OP_form_tls_address"; + case DW_OP_call_frame_cfa: return "OP_call_frame_cfa"; + case DW_OP_lo_user: return "OP_lo_user"; + case DW_OP_hi_user: return "OP_hi_user"; + } + assert(0 && "Unknown Dwarf Operation Encoding"); + return ""; + } + + /// AttributeEncodingString - Return the string for the specified attribute + /// encoding. + const char *AttributeEncodingString(unsigned Encoding) { + switch(Encoding) { + case DW_ATE_address: return "ATE_address"; + case DW_ATE_boolean: return "ATE_boolean"; + case DW_ATE_complex_float: return "ATE_complex_float"; + case DW_ATE_float: return "ATE_float"; + case DW_ATE_signed: return "ATE_signed"; + case DW_ATE_signed_char: return "ATE_signed_char"; + case DW_ATE_unsigned: return "ATE_unsigned"; + case DW_ATE_unsigned_char: return "ATE_unsigned_char"; + case DW_ATE_imaginary_float: return "ATE_imaginary_float"; + case DW_ATE_packed_decimal: return "ATE_packed_decimal"; + case DW_ATE_numeric_string: return "ATE_numeric_string"; + case DW_ATE_edited: return "ATE_edited"; + case DW_ATE_signed_fixed: return "ATE_signed_fixed"; + case DW_ATE_unsigned_fixed: return "ATE_unsigned_fixed"; + case DW_ATE_decimal_float: return "ATE_decimal_float"; + case DW_ATE_lo_user: return "ATE_lo_user"; + case DW_ATE_hi_user: return "ATE_hi_user"; + } + assert(0 && "Unknown Dwarf Attribute Encoding"); + return ""; + } + + /// DecimalSignString - Return the string for the specified decimal sign + /// attribute. + const char *DecimalSignString(unsigned Sign) { + switch(Sign) { + case DW_DS_unsigned: return "DS_unsigned"; + case DW_DS_leading_overpunch: return "DS_leading_overpunch"; + case DW_DS_trailing_overpunch: return "DS_trailing_overpunch"; + case DW_DS_leading_separate: return "DS_leading_separate"; + case DW_DS_trailing_separate: return "DS_trailing_separate"; + } + assert(0 && "Unknown Dwarf Decimal Sign Attribute"); + return ""; + } + + /// EndianityString - Return the string for the specified endianity. + /// + const char *EndianityString(unsigned Endian) { + switch(Endian) { + case DW_END_default: return "END_default"; + case DW_END_big: return "END_big"; + case DW_END_little: return "END_little"; + case DW_END_lo_user: return "END_lo_user"; + case DW_END_hi_user: return "END_hi_user"; + } + assert(0 && "Unknown Dwarf Endianity"); + return ""; + } + + /// AccessibilityString - Return the string for the specified accessibility. + /// + const char *AccessibilityString(unsigned Access) { + switch(Access) { + // Accessibility codes + case DW_ACCESS_public: return "ACCESS_public"; + case DW_ACCESS_protected: return "ACCESS_protected"; + case DW_ACCESS_private: return "ACCESS_private"; + } + assert(0 && "Unknown Dwarf Accessibility"); + return ""; + } + + /// VisibilityString - Return the string for the specified visibility. + /// + const char *VisibilityString(unsigned Visibility) { + switch(Visibility) { + case DW_VIS_local: return "VIS_local"; + case DW_VIS_exported: return "VIS_exported"; + case DW_VIS_qualified: return "VIS_qualified"; + } + assert(0 && "Unknown Dwarf Visibility"); + return ""; + } + + /// VirtualityString - Return the string for the specified virtuality. + /// + const char *VirtualityString(unsigned Virtuality) { + switch(Virtuality) { + case DW_VIRTUALITY_none: return "VIRTUALITY_none"; + case DW_VIRTUALITY_virtual: return "VIRTUALITY_virtual"; + case DW_VIRTUALITY_pure_virtual: return "VIRTUALITY_pure_virtual"; + } + assert(0 && "Unknown Dwarf Virtuality"); + return ""; + } + + /// LanguageString - Return the string for the specified language. + /// + const char *LanguageString(unsigned Language) { + switch(Language) { + case DW_LANG_C89: return "LANG_C89"; + case DW_LANG_C: return "LANG_C"; + case DW_LANG_Ada83: return "LANG_Ada83"; + case DW_LANG_C_plus_plus: return "LANG_C_plus_plus"; + case DW_LANG_Cobol74: return "LANG_Cobol74"; + case DW_LANG_Cobol85: return "LANG_Cobol85"; + case DW_LANG_Fortran77: return "LANG_Fortran77"; + case DW_LANG_Fortran90: return "LANG_Fortran90"; + case DW_LANG_Pascal83: return "LANG_Pascal83"; + case DW_LANG_Modula2: return "LANG_Modula2"; + case DW_LANG_Java: return "LANG_Java"; + case DW_LANG_C99: return "LANG_C99"; + case DW_LANG_Ada95: return "LANG_Ada95"; + case DW_LANG_Fortran95: return "LANG_Fortran95"; + case DW_LANG_PLI: return "LANG_PLI"; + case DW_LANG_ObjC: return "LANG_ObjC"; + case DW_LANG_ObjC_plus_plus: return "LANG_ObjC_plus_plus"; + case DW_LANG_UPC: return "LANG_UPC"; + case DW_LANG_D: return "LANG_D"; + case DW_LANG_lo_user: return "LANG_lo_user"; + case DW_LANG_hi_user: return "LANG_hi_user"; + } + assert(0 && "Unknown Dwarf Language"); + return ""; + } + + /// CaseString - Return the string for the specified identifier case. + /// + const char *CaseString(unsigned Case) { + switch(Case) { + case DW_ID_case_sensitive: return "ID_case_sensitive"; + case DW_ID_up_case: return "ID_up_case"; + case DW_ID_down_case: return "ID_down_case"; + case DW_ID_case_insensitive: return "ID_case_insensitive"; + } + assert(0 && "Unknown Dwarf Identifier Case"); + return ""; + } + + /// ConventionString - Return the string for the specified calling convention. + /// + const char *ConventionString(unsigned Convention) { + switch(Convention) { + case DW_CC_normal: return "CC_normal"; + case DW_CC_program: return "CC_program"; + case DW_CC_nocall: return "CC_nocall"; + case DW_CC_lo_user: return "CC_lo_user"; + case DW_CC_hi_user: return "CC_hi_user"; + } + assert(0 && "Unknown Dwarf Calling Convention"); + return ""; + } + + /// InlineCodeString - Return the string for the specified inline code. + /// + const char *InlineCodeString(unsigned Code) { + switch(Code) { + case DW_INL_not_inlined: return "INL_not_inlined"; + case DW_INL_inlined: return "INL_inlined"; + case DW_INL_declared_not_inlined: return "INL_declared_not_inlined"; + case DW_INL_declared_inlined: return "INL_declared_inlined"; + } + assert(0 && "Unknown Dwarf Inline Code"); + return ""; + } + + /// ArrayOrderString - Return the string for the specified array order. + /// + const char *ArrayOrderString(unsigned Order) { + switch(Order) { + case DW_ORD_row_major: return "ORD_row_major"; + case DW_ORD_col_major: return "ORD_col_major"; + } + assert(0 && "Unknown Dwarf Array Order"); + return ""; + } + + /// DiscriminantString - Return the string for the specified discriminant + /// descriptor. + const char *DiscriminantString(unsigned Discriminant) { + switch(Discriminant) { + case DW_DSC_label: return "DSC_label"; + case DW_DSC_range: return "DSC_range"; + } + assert(0 && "Unknown Dwarf Discriminant Descriptor"); + return ""; + } + + /// LNStandardString - Return the string for the specified line number standard. + /// + const char *LNStandardString(unsigned Standard) { + switch(Standard) { + case DW_LNS_copy: return "LNS_copy"; + case DW_LNS_advance_pc: return "LNS_advance_pc"; + case DW_LNS_advance_line: return "LNS_advance_line"; + case DW_LNS_set_file: return "LNS_set_file"; + case DW_LNS_set_column: return "LNS_set_column"; + case DW_LNS_negate_stmt: return "LNS_negate_stmt"; + case DW_LNS_set_basic_block: return "LNS_set_basic_block"; + case DW_LNS_const_add_pc: return "LNS_const_add_pc"; + case DW_LNS_fixed_advance_pc: return "LNS_fixed_advance_pc"; + case DW_LNS_set_prologue_end: return "LNS_set_prologue_end"; + case DW_LNS_set_epilogue_begin: return "LNS_set_epilogue_begin"; + case DW_LNS_set_isa: return "LNS_set_isa"; + } + assert(0 && "Unknown Dwarf Line Number Standard"); + return ""; + } + + /// LNExtendedString - Return the string for the specified line number extended + /// opcode encodings. + const char *LNExtendedString(unsigned Encoding) { + switch(Encoding) { + // Line Number Extended Opcode Encodings + case DW_LNE_end_sequence: return "LNE_end_sequence"; + case DW_LNE_set_address: return "LNE_set_address"; + case DW_LNE_define_file: return "LNE_define_file"; + case DW_LNE_lo_user: return "LNE_lo_user"; + case DW_LNE_hi_user: return "LNE_hi_user"; + } + assert(0 && "Unknown Dwarf Line Number Extended Opcode Encoding"); + return ""; + } + + /// MacinfoString - Return the string for the specified macinfo type encodings. + /// + const char *MacinfoString(unsigned Encoding) { + switch(Encoding) { + // Macinfo Type Encodings + case DW_MACINFO_define: return "MACINFO_define"; + case DW_MACINFO_undef: return "MACINFO_undef"; + case DW_MACINFO_start_file: return "MACINFO_start_file"; + case DW_MACINFO_end_file: return "MACINFO_end_file"; + case DW_MACINFO_vendor_ext: return "MACINFO_vendor_ext"; + } + assert(0 && "Unknown Dwarf Macinfo Type Encodings"); + return ""; + } + + /// CallFrameString - Return the string for the specified call frame instruction + /// encodings. + const char *CallFrameString(unsigned Encoding) { + switch(Encoding) { + case DW_CFA_advance_loc: return "CFA_advance_loc"; + case DW_CFA_offset: return "CFA_offset"; + case DW_CFA_restore: return "CFA_restore"; + case DW_CFA_set_loc: return "CFA_set_loc"; + case DW_CFA_advance_loc1: return "CFA_advance_loc1"; + case DW_CFA_advance_loc2: return "CFA_advance_loc2"; + case DW_CFA_advance_loc4: return "CFA_advance_loc4"; + case DW_CFA_offset_extended: return "CFA_offset_extended"; + case DW_CFA_restore_extended: return "CFA_restore_extended"; + case DW_CFA_undefined: return "CFA_undefined"; + case DW_CFA_same_value: return "CFA_same_value"; + case DW_CFA_register: return "CFA_register"; + case DW_CFA_remember_state: return "CFA_remember_state"; + case DW_CFA_restore_state: return "CFA_restore_state"; + case DW_CFA_def_cfa: return "CFA_def_cfa"; + case DW_CFA_def_cfa_register: return "CFA_def_cfa_register"; + case DW_CFA_def_cfa_offset: return "CFA_def_cfa_offset"; + case DW_CFA_def_cfa_expression: return "CFA_def_cfa_expression"; + case DW_CFA_expression: return "CFA_expression"; + case DW_CFA_offset_extended_sf: return "CFA_offset_extended_sf"; + case DW_CFA_def_cfa_sf: return "CFA_def_cfa_sf"; + case DW_CFA_def_cfa_offset_sf: return "CFA_def_cfa_offset_sf"; + case DW_CFA_val_offset: return "CFA_val_offset"; + case DW_CFA_val_offset_sf: return "CFA_val_offset_sf"; + case DW_CFA_val_expression: return "CFA_val_expression"; + case DW_CFA_lo_user: return "CFA_lo_user"; + case DW_CFA_hi_user: return "CFA_hi_user"; + } + assert(0 && "Unknown Dwarf Call Frame Instruction Encodings"); + return ""; + } + + } // End of namespace llvm. + From jlaskey at apple.com Mon Feb 27 06:43:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 06:43:43 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h Message-ID: <200602271243.GAA07729@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.25 -> 1.26 --- Log message: Re-orging file. --- Diffs of the changes: (+383 -700) DwarfWriter.h | 1083 ++++++++++++++++++++-------------------------------------- 1 files changed, 383 insertions(+), 700 deletions(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.25 llvm/include/llvm/CodeGen/DwarfWriter.h:1.26 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.25 Thu Feb 23 10:58:18 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Mon Feb 27 06:43:29 2006 @@ -28,728 +28,411 @@ namespace llvm { + +// Forward declarations. + +class AsmPrinter; +class CompileUnitDesc; +class DebugInfoDesc; +class DIE; +class DIEAbbrev; +class GlobalVariableDesc; +class MachineDebugInfo; +class MachineFunction; +class Module; +class SubprogramDesc; +class Type; +class TypeDesc; + +//===----------------------------------------------------------------------===// +// DWLabel - Labels are used to track locations in the assembler file. +// Labels appear in the form debug_, where the tag is a +// category of label (Ex. location) and number is a value unique in that +// category. +class DWLabel { +public: + const char *Tag; // Label category tag. Should always be + // a staticly declared C string. + unsigned Number; // Unique number. + + DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {} +}; + +//===----------------------------------------------------------------------===// +// DwarfWriter - Emits Dwarf debug and exception handling directives. +// +class DwarfWriter { +protected: + //===--------------------------------------------------------------------===// - // Forward declarations. + // Core attributes used by the Dwarf writer. // - class AsmPrinter; - class CompileUnitDesc; - class DebugInfoDesc; - class DIE; - class DwarfWriter; - class GlobalVariableDesc; - class MachineDebugInfo; - class MachineFunction; - class Module; - class SubprogramDesc; - class Type; - class TypeDesc; - //===--------------------------------------------------------------------===// - // DWLabel - Labels are used to track locations in the assembler file. - // Labels appear in the form debug_, where the tag is a - // category of label (Ex. location) and number is a value unique in that - // category. - class DWLabel { - public: - const char *Tag; // Label category tag. Should always be - // a staticly declared C string. - unsigned Number; // Unique number. - - DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {} - }; + // + /// O - Stream to .s file. + /// + std::ostream &O; + + /// Asm - Target of Dwarf emission. + /// + AsmPrinter *Asm; - //===--------------------------------------------------------------------===// - // DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a - // Dwarf abbreviation. - class DIEAbbrevData { - private: - unsigned Attribute; // Dwarf attribute code. - unsigned Form; // Dwarf form code. - - public: - DIEAbbrevData(unsigned A, unsigned F) - : Attribute(A) - , Form(F) - {} - - // Accessors - unsigned getAttribute() const { return Attribute; } - unsigned getForm() const { return Form; } - - /// operator== - Used by DIEAbbrev to locate entry. - /// - bool operator==(const DIEAbbrevData &DAD) const { - return Attribute == DAD.Attribute && Form == DAD.Form; - } - - /// operator!= - Used by DIEAbbrev to locate entry. - /// - bool operator!=(const DIEAbbrevData &DAD) const { - return Attribute != DAD.Attribute || Form != DAD.Form; - } - - /// operator< - Used by DIEAbbrev to locate entry. - /// - bool operator<(const DIEAbbrevData &DAD) const { - return Attribute < DAD.Attribute || - (Attribute == DAD.Attribute && Form < DAD.Form); - } - }; + /// DebugInfo - Collected debug information. + /// + MachineDebugInfo *DebugInfo; + + /// didInitial - Flag to indicate if initial emission has been done. + /// + bool didInitial; //===--------------------------------------------------------------------===// - // DIEAbbrev - Dwarf abbreviation, describes the organization of a debug - // information object. - class DIEAbbrev { - private: - unsigned Tag; // Dwarf tag code. - unsigned ChildrenFlag; // Dwarf children flag. - std::vector Data; // Raw data bytes for abbreviation. - - public: - - DIEAbbrev(unsigned T, unsigned C) - : Tag(T) - , ChildrenFlag(C) - , Data() - {} - ~DIEAbbrev() {} - - // Accessors - unsigned getTag() const { return Tag; } - unsigned getChildrenFlag() const { return ChildrenFlag; } - const std::vector &getData() const { return Data; } - void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; } - - /// operator== - Used by UniqueVector to locate entry. - /// - bool operator==(const DIEAbbrev &DA) const; - - /// operator< - Used by UniqueVector to locate entry. - /// - bool operator<(const DIEAbbrev &DA) const; - - /// AddAttribute - Adds another set of attribute information to the - /// abbreviation. - void AddAttribute(unsigned Attribute, unsigned Form) { - Data.push_back(DIEAbbrevData(Attribute, Form)); - } - - /// Emit - Print the abbreviation using the specified Dwarf writer. - /// - void Emit(const DwarfWriter &DW) const; - -#ifndef NDEBUG - void print(std::ostream &O); - void dump(); -#endif - }; - - //===--------------------------------------------------------------------===// - // DIEValue - A debug information entry value. + // Attributes used to construct specific Dwarf sections. // - class DIEValue { - public: - enum { - isInteger, - isString, - isLabel, - isAsIsLabel, - isDelta, - isEntry - }; - - unsigned Type; // Type of the value - - DIEValue(unsigned T) : Type(T) {} - virtual ~DIEValue() {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *) { return true; } - - /// EmitValue - Emit value via the Dwarf writer. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const = 0; - - /// SizeOf - Return the size of a value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const = 0; - }; - - //===--------------------------------------------------------------------===// - // DWInteger - An integer value DIE. - // - class DIEInteger : public DIEValue { - private: - uint64_t Integer; - - public: - DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEInteger *) { return true; } - static bool classof(const DIEValue *I) { return I->Type == isInteger; } - - /// EmitValue - Emit integer of appropriate size. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - - /// SizeOf - Determine size of integer value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; - }; - + + /// CompileUnits - All the compile units involved in this build. The index + /// of each entry in this vector corresponds to the sources in DebugInfo. + std::vector CompileUnits; + + /// Abbreviations - A UniqueVector of TAG structure abbreviations. + /// + UniqueVector Abbreviations; + + /// GlobalTypes - A map of globally visible named types. + /// + std::map GlobalTypes; + + /// GlobalEntities - A map of globally visible named entities. + /// + std::map GlobalEntities; + + /// StringPool - A UniqueVector of strings used by indirect references. + /// + UniqueVector StringPool; + + /// DescToDieMap - Tracks the mapping of debug informaton descriptors to + /// DIES. + std::map DescToDieMap; + + /// TypeToDieMap - Type to DIEType map. + /// + // FIXME - Should not be needed. + std::map TypeToDieMap; + //===--------------------------------------------------------------------===// - // DIEString - A string value DIE. - // - struct DIEString : public DIEValue { - const std::string String; - - DIEString(const std::string &S) : DIEValue(isString), String(S) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEString *) { return true; } - static bool classof(const DIEValue *S) { return S->Type == isString; } - - /// EmitValue - Emit string value. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - - /// SizeOf - Determine size of string value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; - }; + // Properties to be set by the derived class ctor, used to configure the + // Dwarf writer. + // + + /// AddressSize - Size of addresses used in file. + /// + unsigned AddressSize; + + /// hasLEB128 - True if target asm supports leb128 directives. + /// + bool hasLEB128; /// Defaults to false. + + /// hasDotLoc - True if target asm supports .loc directives. + /// + bool hasDotLoc; /// Defaults to false. + + /// hasDotFile - True if target asm supports .file directives. + /// + bool hasDotFile; /// Defaults to false. + + /// needsSet - True if target asm can't compute addresses on data + /// directives. + bool needsSet; /// Defaults to false. + + /// DwarfAbbrevSection - Section directive for Dwarf abbrev. + /// + const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev". + + /// DwarfInfoSection - Section directive for Dwarf info. + /// + const char *DwarfInfoSection; /// Defaults to ".debug_info". + + /// DwarfLineSection - Section directive for Dwarf info. + /// + const char *DwarfLineSection; /// Defaults to ".debug_line". + + /// DwarfFrameSection - Section directive for Dwarf info. + /// + const char *DwarfFrameSection; /// Defaults to ".debug_frame". + + /// DwarfPubNamesSection - Section directive for Dwarf info. + /// + const char *DwarfPubNamesSection; /// Defaults to ".debug_pubnames". + + /// DwarfPubTypesSection - Section directive for Dwarf info. + /// + const char *DwarfPubTypesSection; /// Defaults to ".debug_pubtypes". + + /// DwarfStrSection - Section directive for Dwarf info. + /// + const char *DwarfStrSection; /// Defaults to ".debug_str". + + /// DwarfLocSection - Section directive for Dwarf info. + /// + const char *DwarfLocSection; /// Defaults to ".debug_loc". + + /// DwarfARangesSection - Section directive for Dwarf info. + /// + const char *DwarfARangesSection; /// Defaults to ".debug_aranges". + + /// DwarfRangesSection - Section directive for Dwarf info. + /// + const char *DwarfRangesSection; /// Defaults to ".debug_ranges". + + /// DwarfMacInfoSection - Section directive for Dwarf info. + /// + const char *DwarfMacInfoSection; /// Defaults to ".debug_macinfo". + + /// TextSection - Section directive for standard text. + /// + const char *TextSection; /// Defaults to ".text". + + /// DataSection - Section directive for standard data. + /// + const char *DataSection; /// Defaults to ".data". //===--------------------------------------------------------------------===// - // DIEDwarfLabel - A Dwarf internal label expression DIE. + // Emission and print routines // - struct DIEDwarfLabel : public DIEValue { - const DWLabel Label; - - DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEDwarfLabel *) { return true; } - static bool classof(const DIEValue *L) { return L->Type == isLabel; } - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; - }; +public: + /// getAddressSize - Return the size of a target address in bytes. + /// + unsigned getAddressSize() const { return AddressSize; } + + /// PrintHex - Print a value as a hexidecimal value. + /// + void PrintHex(int Value) const; + + /// EOL - Print a newline character to asm stream. If a comment is present + /// then it will be printed first. Comments should not contain '\n'. + void EOL(const std::string &Comment) const; + + /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an + /// unsigned leb128 value. + void EmitULEB128Bytes(unsigned Value) const; + + /// EmitSLEB128Bytes - print an assembler byte data directive to compose a + /// signed leb128 value. + void EmitSLEB128Bytes(int Value) const; + + /// PrintULEB128 - Print a series of hexidecimal values (separated by + /// commas) representing an unsigned leb128 value. + void PrintULEB128(unsigned Value) const; + + /// SizeULEB128 - Compute the number of bytes required for an unsigned + /// leb128 value. + static unsigned SizeULEB128(unsigned Value); + + /// PrintSLEB128 - Print a series of hexidecimal values (separated by + /// commas) representing a signed leb128 value. + void PrintSLEB128(int Value) const; + + /// SizeSLEB128 - Compute the number of bytes required for a signed leb128 + /// value. + static unsigned SizeSLEB128(int Value); + + /// EmitInt8 - Emit a byte directive and value. + /// + void EmitInt8(int Value) const; + + /// EmitInt16 - Emit a short directive and value. + /// + void EmitInt16(int Value) const; + + /// EmitInt32 - Emit a long directive and value. + /// + void EmitInt32(int Value) const; + + /// EmitInt64 - Emit a long long directive and value. + /// + void EmitInt64(uint64_t Value) const; + + /// EmitString - Emit a string with quotes and a null terminator. + /// Special characters are emitted properly. (Eg. '\t') + void EmitString(const std::string &String) const; + + /// PrintLabelName - Print label name in form used by Dwarf writer. + /// + void PrintLabelName(DWLabel Label) const { + PrintLabelName(Label.Tag, Label.Number); + } + void PrintLabelName(const char *Tag, unsigned Number) const; + + /// EmitLabel - Emit location label for internal use by Dwarf. + /// + void EmitLabel(DWLabel Label) const { + EmitLabel(Label.Tag, Label.Number); + } + void EmitLabel(const char *Tag, unsigned Number) const; + + /// EmitReference - Emit a reference to a label. + /// + void EmitReference(DWLabel Label) const { + EmitReference(Label.Tag, Label.Number); + } + void EmitReference(const char *Tag, unsigned Number) const; + void EmitReference(const std::string &Name) const; + + /// EmitDifference - Emit the difference between two labels. Some + /// assemblers do not behave with absolute expressions with data directives, + /// so there is an option (needsSet) to use an intermediary set expression. + void EmitDifference(DWLabel LabelHi, DWLabel LabelLo) const { + EmitDifference(LabelHi.Tag, LabelHi.Number, LabelLo.Tag, LabelLo.Number); + } + void EmitDifference(const char *TagHi, unsigned NumberHi, + const char *TagLo, unsigned NumberLo) const; + + /// NewAbbreviation - Add the abbreviation to the Abbreviation vector. + /// + unsigned NewAbbreviation(DIEAbbrev *Abbrev); + + /// NewString - Add a string to the constant pool and returns a label. + /// + DWLabel NewString(const std::string &String); + + /// NewBasicType - Creates a new basic type if necessary, then adds to the + /// owner. + /// FIXME - Should never be needed. + DIE *NewBasicType(DIE *Owner, Type *Ty); + + /// NewGlobalType - Make the type visible globally using the given name. + /// + void NewGlobalType(const std::string &Name, DIE *Type); + + /// NewGlobalEntity - Make the entity visible globally using the given name. + /// + void NewGlobalEntity(const std::string &Name, DIE *Entity); - //===--------------------------------------------------------------------===// - // DIEObjectLabel - A label to an object in code or data. - // - struct DIEObjectLabel : public DIEValue { - const std::string Label; - - DIEObjectLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEObjectLabel *) { return true; } - static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; } - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; - }; +private: - //===--------------------------------------------------------------------===// - // DIEDelta - A simple label difference DIE. - // - struct DIEDelta : public DIEValue { - const DWLabel LabelHi; - const DWLabel LabelLo; - - DIEDelta(const DWLabel &Hi, const DWLabel &Lo) - : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEDelta *) { return true; } - static bool classof(const DIEValue *D) { return D->Type == isDelta; } - - /// EmitValue - Emit delta value. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - - /// SizeOf - Determine size of delta value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; - }; + /// NewType - Create a new type DIE. + /// + DIE *NewType(DIE *Unit, TypeDesc *TyDesc); - //===--------------------------------------------------------------------===// - // DIEntry - A pointer to a debug information entry. - // - struct DIEntry : public DIEValue { - DIE *Entry; - - DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEntry *) { return true; } - static bool classof(const DIEValue *E) { return E->Type == isEntry; } - - /// EmitValue - Emit delta value. - /// - virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - - /// SizeOf - Determine size of delta value in bytes. - /// - virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; - }; + /// NewCompileUnit - Create new compile unit DIE. + /// + DIE *NewCompileUnit(CompileUnitDesc *CompileUnit); - //===--------------------------------------------------------------------===// - // DIE - A structured debug information entry. Has an abbreviation which - // describes it's organization. - class DIE { - private: - DIEAbbrev *Abbrev; // Temporary buffer for abbreviation. - unsigned AbbrevID; // Decribing abbreviation ID. - unsigned Offset; // Offset in debug info section. - unsigned Size; // Size of instance + children. - std::vector Children; // Children DIEs. - std::vector Values; // Attributes values. - - public: - DIE(unsigned Tag); - ~DIE(); - - // Accessors - unsigned getAbbrevID() const { return AbbrevID; } - unsigned getOffset() const { return Offset; } - unsigned getSize() const { return Size; } - const std::vector &getChildren() const { return Children; } - const std::vector &getValues() const { return Values; } - void setOffset(unsigned O) { Offset = O; } - void setSize(unsigned S) { Size = S; } - - /// SiblingOffset - Return the offset of the debug information entry's - /// sibling. - unsigned SiblingOffset() const { return Offset + Size; } - - /// AddUInt - Add an unsigned integer attribute data and value. - /// - void AddUInt(unsigned Attribute, unsigned Form, uint64_t Integer); - - /// AddSInt - Add an signed integer attribute data and value. - /// - void AddSInt(unsigned Attribute, unsigned Form, int64_t Integer); - - /// AddString - Add a std::string attribute data and value. - /// - void AddString(unsigned Attribute, unsigned Form, - const std::string &String); - - /// AddLabel - Add a Dwarf label attribute data and value. - /// - void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label); - - /// AddObjectLabel - Add a non-Dwarf label attribute data and value. - /// - void AddObjectLabel(unsigned Attribute, unsigned Form, - const std::string &Label); - - /// AddDelta - Add a label delta attribute data and value. - /// - void AddDelta(unsigned Attribute, unsigned Form, - const DWLabel &Hi, const DWLabel &Lo); - - /// AddDIEntry - Add a DIE attribute data and value. - /// - void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry); - - /// Complete - Indicate that all attributes have been added and - /// ready to get an abbreviation ID. - /// - void Complete(DwarfWriter &DW); - - /// AddChild - Add a child to the DIE. - void AddChild(DIE *Child); - }; + /// NewGlobalVariable - Make a new global variable DIE. + /// + DIE *NewGlobalVariable(GlobalVariableDesc *GVD); + + /// NewSubprogram - Add a new subprogram DIE. + /// + DIE *NewSubprogram(SubprogramDesc *SPD); + + /// EmitInitial - Emit initial Dwarf declarations. + /// + void EmitInitial() const; - //===--------------------------------------------------------------------===// - // DwarfWriter - Emits Dwarf debug and exception handling directives. - // - class DwarfWriter { - protected: + /// EmitDIE - Recusively Emits a debug information entry. + /// + void EmitDIE(DIE *Die) const; + + /// SizeAndOffsetDie - Compute the size and offset of a DIE. + /// + unsigned SizeAndOffsetDie(DIE *Die, unsigned Offset); + + /// SizeAndOffsets - Compute the size and offset of all the DIEs. + /// + void SizeAndOffsets(); + + /// EmitDebugInfo - Emit the debug info section. + /// + void EmitDebugInfo() const; + + /// EmitAbbreviations - Emit the abbreviation section. + /// + void EmitAbbreviations() const; - //===------------------------------------------------------------------===// - // Core attributes used by the Dwarf writer. - // - - // - /// O - Stream to .s file. - /// - std::ostream &O; - - /// Asm - Target of Dwarf emission. - /// - AsmPrinter *Asm; - - /// DebugInfo - Collected debug information. - /// - MachineDebugInfo *DebugInfo; - - /// didInitial - Flag to indicate if initial emission has been done. - /// - bool didInitial; - - //===------------------------------------------------------------------===// - // Attributes used to construct specific Dwarf sections. - // - - /// CompileUnits - All the compile units involved in this build. The index - /// of each entry in this vector corresponds to the sources in DebugInfo. - std::vector CompileUnits; - - /// Abbreviations - A UniqueVector of TAG structure abbreviations. - /// - UniqueVector Abbreviations; - - /// GlobalTypes - A map of globally visible named types. - /// - std::map GlobalTypes; - - /// GlobalEntities - A map of globally visible named entities. - /// - std::map GlobalEntities; - - /// StringPool - A UniqueVector of strings used by indirect references. - /// - UniqueVector StringPool; - - /// DescToDieMap - Tracks the mapping of debug informaton descriptors to - /// DIES. - std::map DescToDieMap; - - /// TypeToDieMap - Type to DIEType map. - /// - // FIXME - Should not be needed. - std::map TypeToDieMap; - - //===------------------------------------------------------------------===// - // Properties to be set by the derived class ctor, used to configure the - // Dwarf writer. - // - - /// AddressSize - Size of addresses used in file. - /// - unsigned AddressSize; - - /// hasLEB128 - True if target asm supports leb128 directives. - /// - bool hasLEB128; /// Defaults to false. - - /// hasDotLoc - True if target asm supports .loc directives. - /// - bool hasDotLoc; /// Defaults to false. - - /// hasDotFile - True if target asm supports .file directives. - /// - bool hasDotFile; /// Defaults to false. - - /// needsSet - True if target asm can't compute addresses on data - /// directives. - bool needsSet; /// Defaults to false. - - /// DwarfAbbrevSection - Section directive for Dwarf abbrev. - /// - const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev". - - /// DwarfInfoSection - Section directive for Dwarf info. - /// - const char *DwarfInfoSection; /// Defaults to ".debug_info". - - /// DwarfLineSection - Section directive for Dwarf info. - /// - const char *DwarfLineSection; /// Defaults to ".debug_line". - - /// DwarfFrameSection - Section directive for Dwarf info. - /// - const char *DwarfFrameSection; /// Defaults to ".debug_frame". - - /// DwarfPubNamesSection - Section directive for Dwarf info. - /// - const char *DwarfPubNamesSection; /// Defaults to ".debug_pubnames". - - /// DwarfPubTypesSection - Section directive for Dwarf info. - /// - const char *DwarfPubTypesSection; /// Defaults to ".debug_pubtypes". - - /// DwarfStrSection - Section directive for Dwarf info. - /// - const char *DwarfStrSection; /// Defaults to ".debug_str". - - /// DwarfLocSection - Section directive for Dwarf info. - /// - const char *DwarfLocSection; /// Defaults to ".debug_loc". - - /// DwarfARangesSection - Section directive for Dwarf info. - /// - const char *DwarfARangesSection; /// Defaults to ".debug_aranges". - - /// DwarfRangesSection - Section directive for Dwarf info. - /// - const char *DwarfRangesSection; /// Defaults to ".debug_ranges". - - /// DwarfMacInfoSection - Section directive for Dwarf info. - /// - const char *DwarfMacInfoSection; /// Defaults to ".debug_macinfo". - - /// TextSection - Section directive for standard text. - /// - const char *TextSection; /// Defaults to ".text". - - /// DataSection - Section directive for standard data. - /// - const char *DataSection; /// Defaults to ".data". - - //===------------------------------------------------------------------===// - // Emission and print routines - // + /// EmitDebugLines - Emit source line information. + /// + void EmitDebugLines() const; + + /// EmitDebugFrame - Emit info into a debug frame section. + /// + void EmitDebugFrame(); + + /// EmitDebugPubNames - Emit info into a debug pubnames section. + /// + void EmitDebugPubNames(); + + /// EmitDebugPubTypes - Emit info into a debug pubtypes section. + /// + void EmitDebugPubTypes(); + + /// EmitDebugStr - Emit info into a debug str section. + /// + void EmitDebugStr(); + + /// EmitDebugLoc - Emit info into a debug loc section. + /// + void EmitDebugLoc(); + + /// EmitDebugARanges - Emit info into a debug aranges section. + /// + void EmitDebugARanges(); + + /// EmitDebugRanges - Emit info into a debug ranges section. + /// + void EmitDebugRanges(); + + /// EmitDebugMacInfo - Emit info into a debug macinfo section. + /// + void EmitDebugMacInfo(); + + /// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and + /// header file. + void ConstructCompileUnitDIEs(); + + /// ConstructGlobalDIEs - Create DIEs for each of the externally visible + /// global variables. + void ConstructGlobalDIEs(Module &M); + + /// ConstructSubprogramDIEs - Create DIEs for each of the externally visible + /// subprograms. + void ConstructSubprogramDIEs(Module &M); + + /// ShouldEmitDwarf - Returns true if Dwarf declarations should be made. + /// When called it also checks to see if debug info is newly available. if + /// so the initial Dwarf headers are emitted. + bool ShouldEmitDwarf(); public: - /// getAddressSize - Return the size of a target address in bytes. - /// - unsigned getAddressSize() const { return AddressSize; } - - /// PrintHex - Print a value as a hexidecimal value. - /// - void PrintHex(int Value) const; - - /// EOL - Print a newline character to asm stream. If a comment is present - /// then it will be printed first. Comments should not contain '\n'. - void EOL(const std::string &Comment) const; - - /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an - /// unsigned leb128 value. - void EmitULEB128Bytes(unsigned Value) const; - - /// EmitSLEB128Bytes - print an assembler byte data directive to compose a - /// signed leb128 value. - void EmitSLEB128Bytes(int Value) const; - - /// PrintULEB128 - Print a series of hexidecimal values (separated by - /// commas) representing an unsigned leb128 value. - void PrintULEB128(unsigned Value) const; - - /// SizeULEB128 - Compute the number of bytes required for an unsigned - /// leb128 value. - static unsigned SizeULEB128(unsigned Value); - - /// PrintSLEB128 - Print a series of hexidecimal values (separated by - /// commas) representing a signed leb128 value. - void PrintSLEB128(int Value) const; - - /// SizeSLEB128 - Compute the number of bytes required for a signed leb128 - /// value. - static unsigned SizeSLEB128(int Value); - - /// EmitInt8 - Emit a byte directive and value. - /// - void EmitInt8(int Value) const; - - /// EmitInt16 - Emit a short directive and value. - /// - void EmitInt16(int Value) const; - - /// EmitInt32 - Emit a long directive and value. - /// - void EmitInt32(int Value) const; - - /// EmitInt64 - Emit a long long directive and value. - /// - void EmitInt64(uint64_t Value) const; - - /// EmitString - Emit a string with quotes and a null terminator. - /// Special characters are emitted properly. (Eg. '\t') - void EmitString(const std::string &String) const; - - /// PrintLabelName - Print label name in form used by Dwarf writer. - /// - void PrintLabelName(DWLabel Label) const { - PrintLabelName(Label.Tag, Label.Number); - } - void PrintLabelName(const char *Tag, unsigned Number) const; - - /// EmitLabel - Emit location label for internal use by Dwarf. - /// - void EmitLabel(DWLabel Label) const { - EmitLabel(Label.Tag, Label.Number); - } - void EmitLabel(const char *Tag, unsigned Number) const; - - /// EmitReference - Emit a reference to a label. - /// - void EmitReference(DWLabel Label) const { - EmitReference(Label.Tag, Label.Number); - } - void EmitReference(const char *Tag, unsigned Number) const; - void EmitReference(const std::string &Name) const; - - /// EmitDifference - Emit the difference between two labels. Some - /// assemblers do not behave with absolute expressions with data directives, - /// so there is an option (needsSet) to use an intermediary set expression. - void EmitDifference(DWLabel LabelHi, DWLabel LabelLo) const { - EmitDifference(LabelHi.Tag, LabelHi.Number, LabelLo.Tag, LabelLo.Number); - } - void EmitDifference(const char *TagHi, unsigned NumberHi, - const char *TagLo, unsigned NumberLo) const; - - /// NewAbbreviation - Add the abbreviation to the Abbreviation vector. - /// - unsigned NewAbbreviation(DIEAbbrev *Abbrev); - - /// NewString - Add a string to the constant pool and returns a label. - /// - DWLabel NewString(const std::string &String); - - /// NewBasicType - Creates a new basic type if necessary, then adds to the - /// owner. - /// FIXME - Should never be needed. - DIE *NewBasicType(DIE *Owner, Type *Ty); - - /// NewGlobalType - Make the type visible globally using the given name. - /// - void NewGlobalType(const std::string &Name, DIE *Type); - - /// NewGlobalEntity - Make the entity visible globally using the given name. - /// - void NewGlobalEntity(const std::string &Name, DIE *Entity); - -private: + + DwarfWriter(std::ostream &OS, AsmPrinter *A); + virtual ~DwarfWriter(); + + /// SetDebugInfo - Set DebugInfo when it's known that pass manager has + /// created it. Set by the target AsmPrinter. + void SetDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; } - /// NewType - Create a new type DIE. - /// - DIE *NewType(DIE *Unit, TypeDesc *TyDesc); - - /// NewCompileUnit - Create new compile unit DIE. - /// - DIE *NewCompileUnit(CompileUnitDesc *CompileUnit); - - /// NewGlobalVariable - Make a new global variable DIE. - /// - DIE *NewGlobalVariable(GlobalVariableDesc *GVD); - - /// NewSubprogram - Add a new subprogram DIE. - /// - DIE *NewSubprogram(SubprogramDesc *SPD); - - /// EmitInitial - Emit initial Dwarf declarations. - /// - void EmitInitial() const; - - /// EmitDIE - Recusively Emits a debug information entry. - /// - void EmitDIE(DIE *Die) const; - - /// SizeAndOffsetDie - Compute the size and offset of a DIE. - /// - unsigned SizeAndOffsetDie(DIE *Die, unsigned Offset); - - /// SizeAndOffsets - Compute the size and offset of all the DIEs. - /// - void SizeAndOffsets(); - - /// EmitDebugInfo - Emit the debug info section. - /// - void EmitDebugInfo() const; - - /// EmitAbbreviations - Emit the abbreviation section. - /// - void EmitAbbreviations() const; - - /// EmitDebugLines - Emit source line information. - /// - void EmitDebugLines() const; - - /// EmitDebugFrame - Emit info into a debug frame section. - /// - void EmitDebugFrame(); - - /// EmitDebugPubNames - Emit info into a debug pubnames section. - /// - void EmitDebugPubNames(); - - /// EmitDebugPubTypes - Emit info into a debug pubtypes section. - /// - void EmitDebugPubTypes(); - - /// EmitDebugStr - Emit info into a debug str section. - /// - void EmitDebugStr(); - - /// EmitDebugLoc - Emit info into a debug loc section. - /// - void EmitDebugLoc(); - - /// EmitDebugARanges - Emit info into a debug aranges section. - /// - void EmitDebugARanges(); - - /// EmitDebugRanges - Emit info into a debug ranges section. - /// - void EmitDebugRanges(); - - /// EmitDebugMacInfo - Emit info into a debug macinfo section. - /// - void EmitDebugMacInfo(); - - /// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and - /// header file. - void ConstructCompileUnitDIEs(); - - /// ConstructGlobalDIEs - Create DIEs for each of the externally visible - /// global variables. - void ConstructGlobalDIEs(Module &M); - - /// ConstructSubprogramDIEs - Create DIEs for each of the externally visible - /// subprograms. - void ConstructSubprogramDIEs(Module &M); - - /// ShouldEmitDwarf - Returns true if Dwarf declarations should be made. - /// When called it also checks to see if debug info is newly available. if - /// so the initial Dwarf headers are emitted. - bool ShouldEmitDwarf(); - - public: - - DwarfWriter(std::ostream &OS, AsmPrinter *A); - virtual ~DwarfWriter(); - - /// SetDebugInfo - Set DebugInfo when it's known that pass manager has - /// created it. Set by the target AsmPrinter. - void SetDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; } - - //===------------------------------------------------------------------===// - // Main entry points. - // - - /// BeginModule - Emit all Dwarf sections that should come prior to the - /// content. - void BeginModule(Module &M); - - /// EndModule - Emit all Dwarf sections that should come after the content. - /// - void EndModule(Module &M); - - /// BeginFunction - Gather pre-function debug information. - /// - void BeginFunction(MachineFunction &MF); - - /// EndFunction - Gather and emit post-function debug information. - /// - void EndFunction(MachineFunction &MF); - }; + //===--------------------------------------------------------------------===// + // Main entry points. + // + + /// BeginModule - Emit all Dwarf sections that should come prior to the + /// content. + void BeginModule(Module &M); + + /// EndModule - Emit all Dwarf sections that should come after the content. + /// + void EndModule(Module &M); + + /// BeginFunction - Gather pre-function debug information. + /// + void BeginFunction(MachineFunction &MF); + + /// EndFunction - Gather and emit post-function debug information. + /// + void EndFunction(MachineFunction &MF); +}; } // end llvm namespace From jlaskey at apple.com Mon Feb 27 06:43:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 06:43:43 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/Dwarf.h Message-ID: <200602271243.GAA07725@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: Dwarf.h updated: 1.1 -> 1.2 --- Log message: Re-orging file. --- Diffs of the changes: (+494 -410) Dwarf.h | 904 ++++++++++++++++++++++++++++++++++------------------------------ 1 files changed, 494 insertions(+), 410 deletions(-) Index: llvm/include/llvm/Support/Dwarf.h diff -u llvm/include/llvm/Support/Dwarf.h:1.1 llvm/include/llvm/Support/Dwarf.h:1.2 --- llvm/include/llvm/Support/Dwarf.h:1.1 Thu Jan 26 08:45:22 2006 +++ llvm/include/llvm/Support/Dwarf.h Mon Feb 27 06:43:29 2006 @@ -16,417 +16,501 @@ #ifndef LLVM_SUPPORT_DWARF_H #define LLVM_SUPPORT_DWARF_H -namespace llvm { +namespace dwarf { - //===--------------------------------------------------------------------===// - // Dwarf constants as gleaned from the DWARF Debugging Information Format V.3 - // reference manual http://dwarf.freestandards.org . - // - enum dwarf_constants { - DWARF_VERSION = 2, - - // Tags - DW_TAG_array_type = 0x01, - DW_TAG_class_type = 0x02, - DW_TAG_entry_point = 0x03, - DW_TAG_enumeration_type = 0x04, - DW_TAG_formal_parameter = 0x05, - DW_TAG_imported_declaration = 0x08, - DW_TAG_label = 0x0a, - DW_TAG_lexical_block = 0x0b, - DW_TAG_member = 0x0d, - DW_TAG_pointer_type = 0x0f, - DW_TAG_reference_type = 0x10, - DW_TAG_compile_unit = 0x11, - DW_TAG_string_type = 0x12, - DW_TAG_structure_type = 0x13, - DW_TAG_subroutine_type = 0x15, - DW_TAG_typedef = 0x16, - DW_TAG_union_type = 0x17, - DW_TAG_unspecified_parameters = 0x18, - DW_TAG_variant = 0x19, - DW_TAG_common_block = 0x1a, - DW_TAG_common_inclusion = 0x1b, - DW_TAG_inheritance = 0x1c, - DW_TAG_inlined_subroutine = 0x1d, - DW_TAG_module = 0x1e, - DW_TAG_ptr_to_member_type = 0x1f, - DW_TAG_set_type = 0x20, - DW_TAG_subrange_type = 0x21, - DW_TAG_with_stmt = 0x22, - DW_TAG_access_declaration = 0x23, - DW_TAG_base_type = 0x24, - DW_TAG_catch_block = 0x25, - DW_TAG_const_type = 0x26, - DW_TAG_constant = 0x27, - DW_TAG_enumerator = 0x28, - DW_TAG_file_type = 0x29, - DW_TAG_friend = 0x2a, - DW_TAG_namelist = 0x2b, - DW_TAG_namelist_item = 0x2c, - DW_TAG_packed_type = 0x2d, - DW_TAG_subprogram = 0x2e, - DW_TAG_template_type_parameter = 0x2f, - DW_TAG_template_value_parameter = 0x30, - DW_TAG_thrown_type = 0x31, - DW_TAG_try_block = 0x32, - DW_TAG_variant_part = 0x33, - DW_TAG_variable = 0x34, - DW_TAG_volatile_type = 0x35, - DW_TAG_dwarf_procedure = 0x36, - DW_TAG_restrict_type = 0x37, - DW_TAG_interface_type = 0x38, - DW_TAG_namespace = 0x39, - DW_TAG_imported_module = 0x3a, - DW_TAG_unspecified_type = 0x3b, - DW_TAG_partial_unit = 0x3c, - DW_TAG_imported_unit = 0x3d, - DW_TAG_condition = 0x3f, - DW_TAG_shared_type = 0x40, - DW_TAG_lo_user = 0x4080, - DW_TAG_hi_user = 0xffff, - - // Children flag - DW_CHILDREN_no = 0x00, - DW_CHILDREN_yes = 0x01, - - // Attributes - DW_AT_sibling = 0x01, - DW_AT_location = 0x02, - DW_AT_name = 0x03, - DW_AT_ordering = 0x09, - DW_AT_byte_size = 0x0b, - DW_AT_bit_offset = 0x0c, - DW_AT_bit_size = 0x0d, - DW_AT_stmt_list = 0x10, - DW_AT_low_pc = 0x11, - DW_AT_high_pc = 0x12, - DW_AT_language = 0x13, - DW_AT_discr = 0x15, - DW_AT_discr_value = 0x16, - DW_AT_visibility = 0x17, - DW_AT_import = 0x18, - DW_AT_string_length = 0x19, - DW_AT_common_reference = 0x1a, - DW_AT_comp_dir = 0x1b, - DW_AT_const_value = 0x1c, - DW_AT_containing_type = 0x1d, - DW_AT_default_value = 0x1e, - DW_AT_inline = 0x20, - DW_AT_is_optional = 0x21, - DW_AT_lower_bound = 0x22, - DW_AT_producer = 0x25, - DW_AT_prototyped = 0x27, - DW_AT_return_addr = 0x2a, - DW_AT_start_scope = 0x2c, - DW_AT_bit_stride = 0x2e, - DW_AT_upper_bound = 0x2f, - DW_AT_abstract_origin = 0x31, - DW_AT_accessibility = 0x32, - DW_AT_address_class = 0x33, - DW_AT_artificial = 0x34, - DW_AT_base_types = 0x35, - DW_AT_calling_convention = 0x36, - DW_AT_count = 0x37, - DW_AT_data_member_location = 0x38, - DW_AT_decl_column = 0x39, - DW_AT_decl_file = 0x3a, - DW_AT_decl_line = 0x3b, - DW_AT_declaration = 0x3c, - DW_AT_discr_list = 0x3d, - DW_AT_encoding = 0x3e, - DW_AT_external = 0x3f, - DW_AT_frame_base = 0x40, - DW_AT_friend = 0x41, - DW_AT_identifier_case = 0x42, - DW_AT_macro_info = 0x43, - DW_AT_namelist_item = 0x44, - DW_AT_priority = 0x45, - DW_AT_segment = 0x46, - DW_AT_specification = 0x47, - DW_AT_static_link = 0x48, - DW_AT_type = 0x49, - DW_AT_use_location = 0x4a, - DW_AT_variable_parameter = 0x4b, - DW_AT_virtuality = 0x4c, - DW_AT_vtable_elem_location = 0x4d, - DW_AT_allocated = 0x4e, - DW_AT_associated = 0x4f, - DW_AT_data_location = 0x50, - DW_AT_byte_stride = 0x51, - DW_AT_entry_pc = 0x52, - DW_AT_use_UTF8 = 0x53, - DW_AT_extension = 0x54, - DW_AT_ranges = 0x55, - DW_AT_trampoline = 0x56, - DW_AT_call_column = 0x57, - DW_AT_call_file = 0x58, - DW_AT_call_line = 0x59, - DW_AT_description = 0x5a, - DW_AT_binary_scale = 0x5b, - DW_AT_decimal_scale = 0x5c, - DW_AT_small = 0x5d, - DW_AT_decimal_sign = 0x5e, - DW_AT_digit_count = 0x5f, - DW_AT_picture_string = 0x60, - DW_AT_mutable = 0x61, - DW_AT_threads_scaled = 0x62, - DW_AT_explicit = 0x63, - DW_AT_object_pointer = 0x64, - DW_AT_endianity = 0x65, - DW_AT_elemental = 0x66, - DW_AT_pure = 0x67, - DW_AT_recursive = 0x68, - DW_AT_lo_user = 0x2000, - DW_AT_hi_user = 0x3fff, - - // Attribute form encodings - DW_FORM_addr = 0x01, - DW_FORM_block2 = 0x03, - DW_FORM_block4 = 0x04, - DW_FORM_data2 = 0x05, - DW_FORM_data4 = 0x06, - DW_FORM_data8 = 0x07, - DW_FORM_string = 0x08, - DW_FORM_block = 0x09, - DW_FORM_block1 = 0x0a, - DW_FORM_data1 = 0x0b, - DW_FORM_flag = 0x0c, - DW_FORM_sdata = 0x0d, - DW_FORM_strp = 0x0e, - DW_FORM_udata = 0x0f, - DW_FORM_ref_addr = 0x10, - DW_FORM_ref1 = 0x11, - DW_FORM_ref2 = 0x12, - DW_FORM_ref4 = 0x13, - DW_FORM_ref8 = 0x14, - DW_FORM_ref_udata = 0x15, - DW_FORM_indirect = 0x16, - - // Operation encodings - DW_OP_addr = 0x03, - DW_OP_deref = 0x06, - DW_OP_const1u = 0x08, - DW_OP_const1s = 0x09, - DW_OP_const2u = 0x0a, - DW_OP_const2s = 0x0b, - DW_OP_const4u = 0x0c, - DW_OP_const4s = 0x0d, - DW_OP_const8u = 0x0e, - DW_OP_const8s = 0x0f, - DW_OP_constu = 0x10, - DW_OP_consts = 0x11, - DW_OP_dup = 0x12, - DW_OP_drop = 0x13, - DW_OP_over = 0x14, - DW_OP_pick = 0x15, - DW_OP_swap = 0x16, - DW_OP_rot = 0x17, - DW_OP_xderef = 0x18, - DW_OP_abs = 0x19, - DW_OP_and = 0x1a, - DW_OP_div = 0x1b, - DW_OP_minus = 0x1c, - DW_OP_mod = 0x1d, - DW_OP_mul = 0x1e, - DW_OP_neg = 0x1f, - DW_OP_not = 0x20, - DW_OP_or = 0x21, - DW_OP_plus = 0x22, - DW_OP_plus_uconst = 0x23, - DW_OP_shl = 0x24, - DW_OP_shr = 0x25, - DW_OP_shra = 0x26, - DW_OP_xor = 0x27, - DW_OP_skip = 0x2f, - DW_OP_bra = 0x28, - DW_OP_eq = 0x29, - DW_OP_ge = 0x2a, - DW_OP_gt = 0x2b, - DW_OP_le = 0x2c, - DW_OP_lt = 0x2d, - DW_OP_ne = 0x2e, - DW_OP_lit0 = 0x30, - DW_OP_lit1 = 0x31, - DW_OP_lit31 = 0x4f, - DW_OP_reg0 = 0x50, - DW_OP_reg1 = 0x51, - DW_OP_reg31 = 0x6f, - DW_OP_breg0 = 0x70, - DW_OP_breg1 = 0x71, - DW_OP_breg31 = 0x8f, - DW_OP_regx = 0x90, - DW_OP_fbreg = 0x91, - DW_OP_bregx = 0x92, - DW_OP_piece = 0x93, - DW_OP_deref_size = 0x94, - DW_OP_xderef_size = 0x95, - DW_OP_nop = 0x96, - DW_OP_push_object_address = 0x97, - DW_OP_call2 = 0x98, - DW_OP_call4 = 0x99, - DW_OP_call_ref = 0x9a, - DW_OP_form_tls_address = 0x9b, - DW_OP_call_frame_cfa = 0x9c, - DW_OP_lo_user = 0xe0, - DW_OP_hi_user = 0xff, - - // Encoding attribute values - DW_ATE_address = 0x01, - DW_ATE_boolean = 0x02, - DW_ATE_complex_float = 0x03, - DW_ATE_float = 0x04, - DW_ATE_signed = 0x05, - DW_ATE_signed_char = 0x06, - DW_ATE_unsigned = 0x07, - DW_ATE_unsigned_char = 0x08, - DW_ATE_imaginary_float = 0x09, - DW_ATE_packed_decimal = 0x0a, - DW_ATE_numeric_string = 0x0b, - DW_ATE_edited = 0x0c, - DW_ATE_signed_fixed = 0x0d, - DW_ATE_unsigned_fixed = 0x0e, - DW_ATE_decimal_float = 0x0f, - DW_ATE_lo_user = 0x80, - DW_ATE_hi_user = 0xff, - - // Decimal sign attribute values - DW_DS_unsigned = 0x01, - DW_DS_leading_overpunch = 0x02, - DW_DS_trailing_overpunch = 0x03, - DW_DS_leading_separate = 0x04, - DW_DS_trailing_separate = 0x05, - - // Endianity attribute values - DW_END_default = 0x00, - DW_END_big = 0x01, - DW_END_little = 0x02, - DW_END_lo_user = 0x40, - DW_END_hi_user = 0xff, - - // Accessibility codes - DW_ACCESS_public = 0x01, - DW_ACCESS_protected = 0x02, - DW_ACCESS_private = 0x03, - - // Visibility codes - DW_VIS_local = 0x01, - DW_VIS_exported = 0x02, - DW_VIS_qualified = 0x03, - - // Virtuality codes - DW_VIRTUALITY_none = 0x00, - DW_VIRTUALITY_virtual = 0x01, - DW_VIRTUALITY_pure_virtual = 0x02, - - // Language names - DW_LANG_C89 = 0x0001, - DW_LANG_C = 0x0002, - DW_LANG_Ada83 = 0x0003, - DW_LANG_C_plus_plus = 0x0004, - DW_LANG_Cobol74 = 0x0005, - DW_LANG_Cobol85 = 0x0006, - DW_LANG_Fortran77 = 0x0007, - DW_LANG_Fortran90 = 0x0008, - DW_LANG_Pascal83 = 0x0009, - DW_LANG_Modula2 = 0x000a, - DW_LANG_Java = 0x000b, - DW_LANG_C99 = 0x000c, - DW_LANG_Ada95 = 0x000d, - DW_LANG_Fortran95 = 0x000e, - DW_LANG_PLI = 0x000f, - DW_LANG_ObjC = 0x0010, - DW_LANG_ObjC_plus_plus = 0x0011, - DW_LANG_UPC = 0x0012, - DW_LANG_D = 0x0013, - DW_LANG_lo_user = 0x8000, - DW_LANG_hi_user = 0xffff, - - // Identifier case codes - DW_ID_case_sensitive = 0x00, - DW_ID_up_case = 0x01, - DW_ID_down_case = 0x02, - DW_ID_case_insensitive = 0x03, - - // Calling convention codes - DW_CC_normal = 0x01, - DW_CC_program = 0x02, - DW_CC_nocall = 0x03, - DW_CC_lo_user = 0x40, - DW_CC_hi_user = 0xff, - - // Inline codes - DW_INL_not_inlined = 0x00, - DW_INL_inlined = 0x01, - DW_INL_declared_not_inlined = 0x02, - DW_INL_declared_inlined = 0x03, - - // Array ordering - DW_ORD_row_major = 0x00, - DW_ORD_col_major = 0x01, - - // Discriminant descriptor values - DW_DSC_label = 0x00, - DW_DSC_range = 0x01, - - // Line Number Standard Opcode Encodings - DW_LNS_copy = 0x01, - DW_LNS_advance_pc = 0x02, - DW_LNS_advance_line = 0x03, - DW_LNS_set_file = 0x04, - DW_LNS_set_column = 0x05, - DW_LNS_negate_stmt = 0x06, - DW_LNS_set_basic_block = 0x07, - DW_LNS_const_add_pc = 0x08, - DW_LNS_fixed_advance_pc = 0x09, - DW_LNS_set_prologue_end = 0x0a, - DW_LNS_set_epilogue_begin = 0x0b, - DW_LNS_set_isa = 0x0c, - - // Line Number Extended Opcode Encodings - DW_LNE_end_sequence = 0x01, - DW_LNE_set_address = 0x02, - DW_LNE_define_file = 0x03, - DW_LNE_lo_user = 0x80, - DW_LNE_hi_user = 0xff, - - // Macinfo Type Encodings - DW_MACINFO_define = 0x01, - DW_MACINFO_undef = 0x02, - DW_MACINFO_start_file = 0x03, - DW_MACINFO_end_file = 0x04, - DW_MACINFO_vendor_ext = 0xff, - - // Call frame instruction encodings - DW_CFA_advance_loc = 0x40, - DW_CFA_offset = 0x80, - DW_CFA_restore = 0xc0, - DW_CFA_set_loc = 0x01, - DW_CFA_advance_loc1 = 0x02, - DW_CFA_advance_loc2 = 0x03, - DW_CFA_advance_loc4 = 0x04, - DW_CFA_offset_extended = 0x05, - DW_CFA_restore_extended = 0x06, - DW_CFA_undefined = 0x07, - DW_CFA_same_value = 0x08, - DW_CFA_register = 0x09, - DW_CFA_remember_state = 0x0a, - DW_CFA_restore_state = 0x0b, - DW_CFA_def_cfa = 0x0c, - DW_CFA_def_cfa_register = 0x0d, - DW_CFA_def_cfa_offset = 0x0e, - DW_CFA_def_cfa_expression = 0x0f, - DW_CFA_expression = 0x10, - DW_CFA_offset_extended_sf = 0x11, - DW_CFA_def_cfa_sf = 0x12, - DW_CFA_def_cfa_offset_sf = 0x13, - DW_CFA_val_offset = 0x14, - DW_CFA_val_offset_sf = 0x15, - DW_CFA_val_expression = 0x16, - DW_CFA_lo_user = 0x1c, - DW_CFA_hi_user = 0x3f - }; +//===----------------------------------------------------------------------===// +// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3 +// reference manual http://dwarf.freestandards.org . +// +enum dwarf_constants { + DWARF_VERSION = 2, -} // End of namespace llvm + // Tags + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + DW_TAG_imported_declaration = 0x08, + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + DW_TAG_member = 0x0d, + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_parameter = 0x2f, + DW_TAG_template_value_parameter = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + DW_TAG_dwarf_procedure = 0x36, + DW_TAG_restrict_type = 0x37, + DW_TAG_interface_type = 0x38, + DW_TAG_namespace = 0x39, + DW_TAG_imported_module = 0x3a, + DW_TAG_unspecified_type = 0x3b, + DW_TAG_partial_unit = 0x3c, + DW_TAG_imported_unit = 0x3d, + DW_TAG_condition = 0x3f, + DW_TAG_shared_type = 0x40, + DW_TAG_lo_user = 0x4080, + DW_TAG_hi_user = 0xffff, + + // Children flag + DW_CHILDREN_no = 0x00, + DW_CHILDREN_yes = 0x01, + + // Attributes + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, + DW_AT_bit_size = 0x0d, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_bit_stride = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, + DW_AT_namelist_item = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + DW_AT_allocated = 0x4e, + DW_AT_associated = 0x4f, + DW_AT_data_location = 0x50, + DW_AT_byte_stride = 0x51, + DW_AT_entry_pc = 0x52, + DW_AT_use_UTF8 = 0x53, + DW_AT_extension = 0x54, + DW_AT_ranges = 0x55, + DW_AT_trampoline = 0x56, + DW_AT_call_column = 0x57, + DW_AT_call_file = 0x58, + DW_AT_call_line = 0x59, + DW_AT_description = 0x5a, + DW_AT_binary_scale = 0x5b, + DW_AT_decimal_scale = 0x5c, + DW_AT_small = 0x5d, + DW_AT_decimal_sign = 0x5e, + DW_AT_digit_count = 0x5f, + DW_AT_picture_string = 0x60, + DW_AT_mutable = 0x61, + DW_AT_threads_scaled = 0x62, + DW_AT_explicit = 0x63, + DW_AT_object_pointer = 0x64, + DW_AT_endianity = 0x65, + DW_AT_elemental = 0x66, + DW_AT_pure = 0x67, + DW_AT_recursive = 0x68, + DW_AT_lo_user = 0x2000, + DW_AT_hi_user = 0x3fff, + + // Attribute form encodings + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16, + + // Operation encodings + DW_OP_addr = 0x03, + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, + DW_OP_const1s = 0x09, + DW_OP_const2u = 0x0a, + DW_OP_const2s = 0x0b, + DW_OP_const4u = 0x0c, + DW_OP_const4s = 0x0d, + DW_OP_const8u = 0x0e, + DW_OP_const8s = 0x0f, + DW_OP_constu = 0x10, + DW_OP_consts = 0x11, + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, + DW_OP_swap = 0x16, + DW_OP_rot = 0x17, + DW_OP_xderef = 0x18, + DW_OP_abs = 0x19, + DW_OP_and = 0x1a, + DW_OP_div = 0x1b, + DW_OP_minus = 0x1c, + DW_OP_mod = 0x1d, + DW_OP_mul = 0x1e, + DW_OP_neg = 0x1f, + DW_OP_not = 0x20, + DW_OP_or = 0x21, + DW_OP_plus = 0x22, + DW_OP_plus_uconst = 0x23, + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_skip = 0x2f, + DW_OP_bra = 0x28, + DW_OP_eq = 0x29, + DW_OP_ge = 0x2a, + DW_OP_gt = 0x2b, + DW_OP_le = 0x2c, + DW_OP_lt = 0x2d, + DW_OP_ne = 0x2e, + DW_OP_lit0 = 0x30, + DW_OP_lit1 = 0x31, + DW_OP_lit31 = 0x4f, + DW_OP_reg0 = 0x50, + DW_OP_reg1 = 0x51, + DW_OP_reg31 = 0x6f, + DW_OP_breg0 = 0x70, + DW_OP_breg1 = 0x71, + DW_OP_breg31 = 0x8f, + DW_OP_regx = 0x90, + DW_OP_fbreg = 0x91, + DW_OP_bregx = 0x92, + DW_OP_piece = 0x93, + DW_OP_deref_size = 0x94, + DW_OP_xderef_size = 0x95, + DW_OP_nop = 0x96, + DW_OP_push_object_address = 0x97, + DW_OP_call2 = 0x98, + DW_OP_call4 = 0x99, + DW_OP_call_ref = 0x9a, + DW_OP_form_tls_address = 0x9b, + DW_OP_call_frame_cfa = 0x9c, + DW_OP_lo_user = 0xe0, + DW_OP_hi_user = 0xff, + + // Encoding attribute values + DW_ATE_address = 0x01, + DW_ATE_boolean = 0x02, + DW_ATE_complex_float = 0x03, + DW_ATE_float = 0x04, + DW_ATE_signed = 0x05, + DW_ATE_signed_char = 0x06, + DW_ATE_unsigned = 0x07, + DW_ATE_unsigned_char = 0x08, + DW_ATE_imaginary_float = 0x09, + DW_ATE_packed_decimal = 0x0a, + DW_ATE_numeric_string = 0x0b, + DW_ATE_edited = 0x0c, + DW_ATE_signed_fixed = 0x0d, + DW_ATE_unsigned_fixed = 0x0e, + DW_ATE_decimal_float = 0x0f, + DW_ATE_lo_user = 0x80, + DW_ATE_hi_user = 0xff, + + // Decimal sign attribute values + DW_DS_unsigned = 0x01, + DW_DS_leading_overpunch = 0x02, + DW_DS_trailing_overpunch = 0x03, + DW_DS_leading_separate = 0x04, + DW_DS_trailing_separate = 0x05, + + // Endianity attribute values + DW_END_default = 0x00, + DW_END_big = 0x01, + DW_END_little = 0x02, + DW_END_lo_user = 0x40, + DW_END_hi_user = 0xff, + + // Accessibility codes + DW_ACCESS_public = 0x01, + DW_ACCESS_protected = 0x02, + DW_ACCESS_private = 0x03, + + // Visibility codes + DW_VIS_local = 0x01, + DW_VIS_exported = 0x02, + DW_VIS_qualified = 0x03, + + // Virtuality codes + DW_VIRTUALITY_none = 0x00, + DW_VIRTUALITY_virtual = 0x01, + DW_VIRTUALITY_pure_virtual = 0x02, + + // Language names + DW_LANG_C89 = 0x0001, + DW_LANG_C = 0x0002, + DW_LANG_Ada83 = 0x0003, + DW_LANG_C_plus_plus = 0x0004, + DW_LANG_Cobol74 = 0x0005, + DW_LANG_Cobol85 = 0x0006, + DW_LANG_Fortran77 = 0x0007, + DW_LANG_Fortran90 = 0x0008, + DW_LANG_Pascal83 = 0x0009, + DW_LANG_Modula2 = 0x000a, + DW_LANG_Java = 0x000b, + DW_LANG_C99 = 0x000c, + DW_LANG_Ada95 = 0x000d, + DW_LANG_Fortran95 = 0x000e, + DW_LANG_PLI = 0x000f, + DW_LANG_ObjC = 0x0010, + DW_LANG_ObjC_plus_plus = 0x0011, + DW_LANG_UPC = 0x0012, + DW_LANG_D = 0x0013, + DW_LANG_lo_user = 0x8000, + DW_LANG_hi_user = 0xffff, + + // Identifier case codes + DW_ID_case_sensitive = 0x00, + DW_ID_up_case = 0x01, + DW_ID_down_case = 0x02, + DW_ID_case_insensitive = 0x03, + + // Calling convention codes + DW_CC_normal = 0x01, + DW_CC_program = 0x02, + DW_CC_nocall = 0x03, + DW_CC_lo_user = 0x40, + DW_CC_hi_user = 0xff, + + // Inline codes + DW_INL_not_inlined = 0x00, + DW_INL_inlined = 0x01, + DW_INL_declared_not_inlined = 0x02, + DW_INL_declared_inlined = 0x03, + + // Array ordering + DW_ORD_row_major = 0x00, + DW_ORD_col_major = 0x01, + + // Discriminant descriptor values + DW_DSC_label = 0x00, + DW_DSC_range = 0x01, + + // Line Number Standard Opcode Encodings + DW_LNS_copy = 0x01, + DW_LNS_advance_pc = 0x02, + DW_LNS_advance_line = 0x03, + DW_LNS_set_file = 0x04, + DW_LNS_set_column = 0x05, + DW_LNS_negate_stmt = 0x06, + DW_LNS_set_basic_block = 0x07, + DW_LNS_const_add_pc = 0x08, + DW_LNS_fixed_advance_pc = 0x09, + DW_LNS_set_prologue_end = 0x0a, + DW_LNS_set_epilogue_begin = 0x0b, + DW_LNS_set_isa = 0x0c, + + // Line Number Extended Opcode Encodings + DW_LNE_end_sequence = 0x01, + DW_LNE_set_address = 0x02, + DW_LNE_define_file = 0x03, + DW_LNE_lo_user = 0x80, + DW_LNE_hi_user = 0xff, + + // Macinfo Type Encodings + DW_MACINFO_define = 0x01, + DW_MACINFO_undef = 0x02, + DW_MACINFO_start_file = 0x03, + DW_MACINFO_end_file = 0x04, + DW_MACINFO_vendor_ext = 0xff, + + // Call frame instruction encodings + DW_CFA_advance_loc = 0x40, + DW_CFA_offset = 0x80, + DW_CFA_restore = 0xc0, + DW_CFA_set_loc = 0x01, + DW_CFA_advance_loc1 = 0x02, + DW_CFA_advance_loc2 = 0x03, + DW_CFA_advance_loc4 = 0x04, + DW_CFA_offset_extended = 0x05, + DW_CFA_restore_extended = 0x06, + DW_CFA_undefined = 0x07, + DW_CFA_same_value = 0x08, + DW_CFA_register = 0x09, + DW_CFA_remember_state = 0x0a, + DW_CFA_restore_state = 0x0b, + DW_CFA_def_cfa = 0x0c, + DW_CFA_def_cfa_register = 0x0d, + DW_CFA_def_cfa_offset = 0x0e, + DW_CFA_def_cfa_expression = 0x0f, + DW_CFA_expression = 0x10, + DW_CFA_offset_extended_sf = 0x11, + DW_CFA_def_cfa_sf = 0x12, + DW_CFA_def_cfa_offset_sf = 0x13, + DW_CFA_val_offset = 0x14, + DW_CFA_val_offset_sf = 0x15, + DW_CFA_val_expression = 0x16, + DW_CFA_lo_user = 0x1c, + DW_CFA_hi_user = 0x3f +}; + +/// TagString - Return the string for the specified tag. +/// +const char *TagString(unsigned Tag); + +/// ChildrenString - Return the string for the specified children flag. +/// +const char *ChildrenString(unsigned Children); + +/// AttributeString - Return the string for the specified attribute. +/// +const char *AttributeString(unsigned Attribute); + +/// FormEncodingString - Return the string for the specified form encoding. +/// +const char *FormEncodingString(unsigned Encoding); + +/// OperationEncodingString - Return the string for the specified operation +/// encoding. +const char *OperationEncodingString(unsigned Encoding); + +/// AttributeEncodingString - Return the string for the specified attribute +/// encoding. +const char *AttributeEncodingString(unsigned Encoding); + +/// DecimalSignString - Return the string for the specified decimal sign +/// attribute. +const char *DecimalSignString(unsigned Sign); + +/// EndianityString - Return the string for the specified endianity. +/// +const char *EndianityString(unsigned Endian); + +/// AccessibilityString - Return the string for the specified accessibility. +/// +const char *AccessibilityString(unsigned Access); + +/// VisibilityString - Return the string for the specified visibility. +/// +const char *VisibilityString(unsigned Visibility); + +/// VirtualityString - Return the string for the specified virtuality. +/// +const char *VirtualityString(unsigned Virtuality); + +/// LanguageString - Return the string for the specified language. +/// +const char *LanguageString(unsigned Language); + +/// CaseString - Return the string for the specified identifier case. +/// +const char *CaseString(unsigned Case); + +/// ConventionString - Return the string for the specified calling convention. +/// +const char *ConventionString(unsigned Convention); + +/// InlineCodeString - Return the string for the specified inline code. +/// +const char *InlineCodeString(unsigned Code); + +/// ArrayOrderString - Return the string for the specified array order. +/// +const char *ArrayOrderString(unsigned Order); + +/// DiscriminantString - Return the string for the specified discriminant +/// descriptor. +const char *DiscriminantString(unsigned Discriminant); + +/// LNStandardString - Return the string for the specified line number standard. +/// +const char *LNStandardString(unsigned Standard); + +/// LNExtendedString - Return the string for the specified line number extended +/// opcode encodings. +const char *LNExtendedString(unsigned Encoding); + +/// MacinfoString - Return the string for the specified macinfo type encodings. +/// +const char *MacinfoString(unsigned Encoding); + +/// CallFrameString - Return the string for the specified call frame instruction +/// encodings. +const char *CallFrameString(unsigned Encoding); + +} // End of namespace dwarf #endif From jlaskey at apple.com Mon Feb 27 11:27:25 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 11:27:25 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h Message-ID: <200602271727.LAA12191@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.26 -> 1.27 --- Log message: Supporting multiple compile units. --- Diffs of the changes: (+16 -27) DwarfWriter.h | 43 ++++++++++++++++--------------------------- 1 files changed, 16 insertions(+), 27 deletions(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.26 llvm/include/llvm/CodeGen/DwarfWriter.h:1.27 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.26 Mon Feb 27 06:43:29 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Mon Feb 27 11:27:12 2006 @@ -32,6 +32,7 @@ // Forward declarations. class AsmPrinter; +class CompileUnit; class CompileUnitDesc; class DebugInfoDesc; class DIE; @@ -43,7 +44,6 @@ class SubprogramDesc; class Type; class TypeDesc; - //===----------------------------------------------------------------------===// // DWLabel - Labels are used to track locations in the assembler file. @@ -92,23 +92,20 @@ /// CompileUnits - All the compile units involved in this build. The index /// of each entry in this vector corresponds to the sources in DebugInfo. - std::vector CompileUnits; + std::vector CompileUnits; /// Abbreviations - A UniqueVector of TAG structure abbreviations. /// UniqueVector Abbreviations; - /// GlobalTypes - A map of globally visible named types. - /// - std::map GlobalTypes; - - /// GlobalEntities - A map of globally visible named entities. - /// - std::map GlobalEntities; - /// StringPool - A UniqueVector of strings used by indirect references. - /// + /// UnitMap - Map debug information descriptor to compile unit. + /// UniqueVector StringPool; + + /// UnitMap - Map debug information descriptor to compile unit. + /// + std::map DescToUnitMap; /// DescToDieMap - Tracks the mapping of debug informaton descriptors to /// DIES. @@ -299,25 +296,21 @@ /// NewBasicType - Creates a new basic type if necessary, then adds to the /// owner. /// FIXME - Should never be needed. - DIE *NewBasicType(DIE *Owner, Type *Ty); - - /// NewGlobalType - Make the type visible globally using the given name. - /// - void NewGlobalType(const std::string &Name, DIE *Type); - - /// NewGlobalEntity - Make the entity visible globally using the given name. - /// - void NewGlobalEntity(const std::string &Name, DIE *Entity); + DIE *NewBasicType(CompileUnit *Unit, Type *Ty); private: /// NewType - Create a new type DIE. /// - DIE *NewType(DIE *Unit, TypeDesc *TyDesc); + DIE *DwarfWriter::NewType(CompileUnit *Unit, TypeDesc *TyDesc); - /// NewCompileUnit - Create new compile unit DIE. + /// NewCompileUnit - Create new compile unit and it's die. /// - DIE *NewCompileUnit(CompileUnitDesc *CompileUnit); + CompileUnit *NewCompileUnit(CompileUnitDesc *UnitDesc, unsigned ID); + + /// FindCompileUnit - Get the compile unit for the given descriptor. + /// + CompileUnit *FindCompileUnit(CompileUnitDesc *UnitDesc); /// NewGlobalVariable - Make a new global variable DIE. /// @@ -363,10 +356,6 @@ /// void EmitDebugPubNames(); - /// EmitDebugPubTypes - Emit info into a debug pubtypes section. - /// - void EmitDebugPubTypes(); - /// EmitDebugStr - Emit info into a debug str section. /// void EmitDebugStr(); From jlaskey at apple.com Mon Feb 27 11:27:25 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 11:27:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200602271727.LAA12187@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.31 -> 1.32 --- Log message: Supporting multiple compile units. --- Diffs of the changes: (+184 -135) DwarfWriter.cpp | 319 ++++++++++++++++++++++++++++++++------------------------ 1 files changed, 184 insertions(+), 135 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.31 llvm/lib/CodeGen/DwarfWriter.cpp:1.32 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.31 Mon Feb 27 06:43:29 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Mon Feb 27 11:27:12 2006 @@ -41,6 +41,41 @@ class DIE; //===----------------------------------------------------------------------===// +class CompileUnit { +private: + CompileUnitDesc *Desc; // Compile unit debug descriptor. + unsigned ID; // File ID for source. + DIE *Die; // Compile unit die. + std::map Globals; // A map of globally visible named + // entities for this unit. + +public: + CompileUnit(CompileUnitDesc *CUD, unsigned I, DIE *D) + : Desc(CUD) + , ID(I) + , Die(D) + , Globals() + {} + + ~CompileUnit(); + + // Accessors. + CompileUnitDesc *getDesc() const { return Desc; } + unsigned getID() const { return ID; } + DIE* getDie() const { return Die; } + std::map &getGlobals() { return Globals; } + + /// hasContent - Return true if this compile unit has something to write out. + /// + bool hasContent() const; + + /// AddGlobal - Add a new global entity to the compile unit. + /// + void AddGlobal(const std::string &Name, DIE *Die); + +}; + +//===----------------------------------------------------------------------===// // DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a // Dwarf abbreviation. class DIEAbbrevData { @@ -54,7 +89,7 @@ , Form(F) {} - // Accessors + // Accessors. unsigned getAttribute() const { return Attribute; } unsigned getForm() const { return Form; } @@ -96,7 +131,7 @@ {} ~DIEAbbrev() {} - // Accessors + // Accessors. unsigned getTag() const { return Tag; } unsigned getChildrenFlag() const { return ChildrenFlag; } const std::vector &getData() const { return Data; } @@ -304,7 +339,7 @@ DIE(unsigned Tag); ~DIE(); - // Accessors + // Accessors. unsigned getAbbrevID() const { return AbbrevID; } unsigned getOffset() const { return Offset; } unsigned getSize() const { return Size; } @@ -361,6 +396,24 @@ //===----------------------------------------------------------------------===// +CompileUnit::~CompileUnit() { + delete Die; +} + +/// hasContent - Return true if this compile unit has something to write out. +/// +bool CompileUnit::hasContent() const { + return !Die->getChildren().empty(); +} + +/// AddGlobal - Add a new global entity to the compile unit. +/// +void CompileUnit::AddGlobal(const std::string &Name, DIE *Die) { + Globals[Name] = Die; +} + +//===----------------------------------------------------------------------===// + /// operator== - Used by UniqueVector to locate entry. /// bool DIEAbbrev::operator==(const DIEAbbrev &DA) const { @@ -914,7 +967,7 @@ /// NewBasicType - Creates a new basic type if necessary, then adds to the /// owner. /// FIXME - Should never be needed. -DIE *DwarfWriter::NewBasicType(DIE *Owner, Type *Ty) { +DIE *DwarfWriter::NewBasicType(CompileUnit *Unit, Type *Ty) { DIE *&Slot = TypeToDieMap[Ty]; if (Slot) return Slot; @@ -988,28 +1041,14 @@ Slot->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); // Add to context owner. - Owner->AddChild(Slot); + Unit->getDie()->AddChild(Slot); return Slot; } -/// NewGlobalType - Make the type visible globally using the given name. -/// -void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) { - assert(!GlobalTypes[Name] && "Duplicate global type"); - GlobalTypes[Name] = Type; -} - -/// NewGlobalEntity - Make the entity visible globally using the given name. -/// -void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) { - assert(!GlobalEntities[Name] && "Duplicate global variable or function"); - GlobalEntities[Name] = Entity; -} - /// NewType - Create a new type DIE. /// -DIE *DwarfWriter::NewType(DIE *Unit, TypeDesc *TyDesc) { +DIE *DwarfWriter::NewType(CompileUnit *Unit, TypeDesc *TyDesc) { // FIXME - hack to get around NULL types short term. if (!TyDesc) return NewBasicType(Unit, Type::IntTy); @@ -1056,37 +1095,50 @@ if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name); // Add source line info if present. if (CompileUnitDesc *File = TyDesc->getFile()) { - unsigned FileID = DebugInfo->RecordSource(File); + CompileUnit *FileUnit = FindCompileUnit(File); + unsigned FileID = FileUnit->getID(); int Line = TyDesc->getLine(); Ty->AddUInt(DW_AT_decl_file, 0, FileID); Ty->AddUInt(DW_AT_decl_line, 0, Line); } // Add to context owner. - Unit->AddChild(Ty); + Unit->getDie()->AddChild(Ty); return Slot; } -/// NewCompileUnit - Create new compile unit DIE. +/// NewCompileUnit - Create new compile unit and it's die. /// -DIE *DwarfWriter::NewCompileUnit(CompileUnitDesc *CompileUnit) { - // Check for pre-existence. - DIE *&Slot = DescToDieMap[CompileUnit]; - if (Slot) return Slot; - - DIE *Unit = new DIE(DW_TAG_compile_unit); - // FIXME - use the correct line set. - Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("section_line", 0)); - Unit->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0)); - Unit->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0)); - Unit->AddString(DW_AT_producer, DW_FORM_string, CompileUnit->getProducer()); - Unit->AddUInt (DW_AT_language, DW_FORM_data1, CompileUnit->getLanguage()); - Unit->AddString(DW_AT_name, DW_FORM_string, CompileUnit->getFileName()); - Unit->AddString(DW_AT_comp_dir, DW_FORM_string, CompileUnit->getDirectory()); +CompileUnit *DwarfWriter::NewCompileUnit(CompileUnitDesc *UnitDesc, + unsigned ID) { + // Construct debug information entry. + DIE *Die = new DIE(DW_TAG_compile_unit); + Die->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0)); + Die->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0)); + Die->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0)); + Die->AddString(DW_AT_producer, DW_FORM_string, UnitDesc->getProducer()); + Die->AddUInt (DW_AT_language, DW_FORM_data1, UnitDesc->getLanguage()); + Die->AddString(DW_AT_name, DW_FORM_string, UnitDesc->getFileName()); + Die->AddString(DW_AT_comp_dir, DW_FORM_string, UnitDesc->getDirectory()); + + // Add die to descriptor map. + DescToDieMap[UnitDesc] = Die; - Slot = Unit; + // Construct compile unit. + CompileUnit *Unit = new CompileUnit(UnitDesc, ID, Die); + // Add Unit to compile unit map. + DescToUnitMap[UnitDesc] = Unit; + + return Unit; +} + +/// FindCompileUnit - Get the compile unit for the given descriptor. +/// +CompileUnit *DwarfWriter::FindCompileUnit(CompileUnitDesc *UnitDesc) { + CompileUnit *Unit = DescToUnitMap[UnitDesc]; + assert(Unit && "Missing compile unit."); return Unit; } @@ -1098,9 +1150,8 @@ if (Slot) return Slot; // Get the compile unit context. - CompileUnitDesc *CompileUnit = - static_cast(GVD->getContext()); - DIE *Unit = NewCompileUnit(CompileUnit); + CompileUnitDesc *UnitDesc = static_cast(GVD->getContext()); + CompileUnit *Unit = FindCompileUnit(UnitDesc); // Get the global variable itself. GlobalVariable *GV = GVD->getGlobalVariable(); // Generate the mangled name. @@ -1108,7 +1159,7 @@ // Gather the details (simplify add attribute code.) const std::string &Name = GVD->getName(); - unsigned FileID = DebugInfo->RecordSource(CompileUnit); + unsigned FileID = Unit->getID(); unsigned Line = GVD->getLine(); // Get the global's type. @@ -1128,10 +1179,11 @@ Slot = VariableDie; // Add to context owner. - Unit->AddChild(VariableDie); + Unit->getDie()->AddChild(VariableDie); // Expose as global. - NewGlobalEntity(Name, VariableDie); + // FIXME - need to check external flag. + Unit->AddGlobal(Name, VariableDie); return VariableDie; } @@ -1144,13 +1196,12 @@ if (Slot) return Slot; // Get the compile unit context. - CompileUnitDesc *CompileUnit = - static_cast(SPD->getContext()); - DIE *Unit = NewCompileUnit(CompileUnit); + CompileUnitDesc *UnitDesc = static_cast(SPD->getContext()); + CompileUnit *Unit = FindCompileUnit(UnitDesc); // Gather the details (simplify add attribute code.) const std::string &Name = SPD->getName(); - unsigned FileID = DebugInfo->RecordSource(CompileUnit); + unsigned FileID = Unit->getID(); // FIXME - faking the line for the time being. unsigned Line = 1; @@ -1168,10 +1219,10 @@ Slot = SubprogramDie; // Add to context owner. - Unit->AddChild(SubprogramDie); + Unit->getDie()->AddChild(SubprogramDie); // Expose as global. - NewGlobalEntity(Name, SubprogramDie); + Unit->AddGlobal(Name, SubprogramDie); return SubprogramDie; } @@ -1312,17 +1363,19 @@ /// SizeAndOffsets - Compute the size and offset of all the DIEs. /// void DwarfWriter::SizeAndOffsets() { - unsigned Offset = 0; // Process each compile unit. for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { - // Compute size of compile unit header - Offset += sizeof(int32_t) + // Length of Compilation Unit Info - sizeof(int16_t) + // DWARF version number - sizeof(int32_t) + // Offset Into Abbrev. Section - sizeof(int8_t); // Pointer Size (in bytes) - - Offset = SizeAndOffsetDie(CompileUnits[i], Offset); + CompileUnit *Unit = CompileUnits[i]; + if (Unit->hasContent()) { + // Compute size of compile unit header + unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + + SizeAndOffsetDie(Unit->getDie(), Offset); + } } } @@ -1332,19 +1385,16 @@ // Start debug info section. Asm->SwitchSection(DwarfInfoSection, 0); - // Get the number of compile units. - unsigned N = CompileUnits.size(); - - // If there are any compile units. - if (N) { - EmitLabel("info_begin", 0); - - // Process each compile unit. - for (unsigned i = 0; i < N; ++i) { + // Process each compile unit. + for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { + CompileUnit *Unit = CompileUnits[i]; + + if (Unit->hasContent()) { + DIE *Die = Unit->getDie(); // Emit the compile units header. - + EmitLabel("info_begin", Unit->getID()); // Emit size of content not including length itself - unsigned ContentSize = CompileUnits[i]->getSize() + + unsigned ContentSize = Die->getSize() + sizeof(int16_t) + // DWARF version number sizeof(int32_t) + // Offset Into Abbrev. Section sizeof(int8_t); // Pointer Size (in bytes) @@ -1354,10 +1404,9 @@ EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section"); EmitInt8(AddressSize); EOL("Address Size (in bytes)"); - EmitDIE(CompileUnits[i]); + EmitDIE(Die); + EmitLabel("info_end", Unit->getID()); } - - EmitLabel("info_end", 0); O << "\n"; } @@ -1493,7 +1542,7 @@ if (Source != LineInfo->getSourceID()) { Source = LineInfo->getSourceID(); EmitInt8(DW_LNS_set_file); EOL("DW_LNS_set_file"); - EmitULEB128Bytes(0); EOL("New Source"); + EmitULEB128Bytes(Source); EOL("New Source"); } // If change of line. @@ -1546,50 +1595,45 @@ /// EmitDebugPubNames - Emit visible names into a debug pubnames section. /// void DwarfWriter::EmitDebugPubNames() { - // Check to see if it is worth the effort. - if (!GlobalEntities.empty()) { - // Start the dwarf pubnames section. - Asm->SwitchSection(DwarfPubNamesSection, 0); - - EmitDifference("pubnames_end", 0, "pubnames_begin", 0); - EOL("Length of Public Names Info"); - - EmitLabel("pubnames_begin", 0); + // Start the dwarf pubnames section. + Asm->SwitchSection(DwarfPubNamesSection, 0); - EmitInt16(DWARF_VERSION); EOL("DWARF Version"); + // Process each compile unit. + for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { + CompileUnit *Unit = CompileUnits[i]; - EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info"); + if (Unit->hasContent()) { + EmitDifference("pubnames_end", Unit->getID(), + "pubnames_begin", Unit->getID()); + EOL("Length of Public Names Info"); + + EmitLabel("pubnames_begin", Unit->getID()); + + EmitInt16(DWARF_VERSION); EOL("DWARF Version"); + + EmitReference("info_begin", Unit->getID()); + EOL("Offset of Compilation Unit Info"); - EmitDifference("info_end", 0, "info_begin", 0); - EOL("Compilation Unit Length"); - - for (std::map::iterator GI = GlobalEntities.begin(), - GE = GlobalEntities.end(); - GI != GE; ++GI) { - const std::string &Name = GI->first; - DIE * Entity = GI->second; + EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID()); + EOL("Compilation Unit Length"); - EmitInt32(Entity->getOffset()); EOL("DIE offset"); - EmitString(Name); EOL("External Name"); + std::map &Globals = Unit->getGlobals(); + for (std::map::iterator GI = Globals.begin(), + GE = Globals.end(); + GI != GE; ++GI) { + const std::string &Name = GI->first; + DIE * Entity = GI->second; + + EmitInt32(Entity->getOffset()); EOL("DIE offset"); + EmitString(Name); EOL("External Name"); + } + + EmitInt32(0); EOL("End Mark"); + EmitLabel("pubnames_end", Unit->getID()); + + O << "\n"; } - - EmitInt32(0); EOL("End Mark"); - EmitLabel("pubnames_end", 0); - - O << "\n"; - } -} - -/// EmitDebugPubTypes - Emit visible names into a debug pubtypes section. -/// -void DwarfWriter::EmitDebugPubTypes() { - // Check to see if it is worth the effort. - if (!GlobalTypes.empty()) { - // Start the dwarf pubtypes section. - Asm->SwitchSection(DwarfPubTypesSection, 0); - - O << "\n"; } } @@ -1631,29 +1675,38 @@ Asm->SwitchSection(DwarfARangesSection, 0); // FIXME - Mock up +#if 0 + // Process each compile unit. + for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) { + CompileUnit *Unit = CompileUnits[i]; + + if (Unit->hasContent()) { + // Don't include size of length + EmitInt32(0x1c); EOL("Length of Address Ranges Info"); + + EmitInt16(DWARF_VERSION); EOL("Dwarf Version"); + + EmitReference("info_begin", Unit->getID()); + EOL("Offset of Compilation Unit Info"); - // Don't include size of length - EmitInt32(0x1c); EOL("Length of Address Ranges Info"); - - EmitInt16(DWARF_VERSION); EOL("Dwarf Version"); - - EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info"); - - EmitInt8(AddressSize); EOL("Size of Address"); + EmitInt8(AddressSize); EOL("Size of Address"); - EmitInt8(0); EOL("Size of Segment Descriptor"); + EmitInt8(0); EOL("Size of Segment Descriptor"); - EmitInt16(0); EOL("Pad (1)"); - EmitInt16(0); EOL("Pad (2)"); + EmitInt16(0); EOL("Pad (1)"); + EmitInt16(0); EOL("Pad (2)"); - // Range 1 - EmitReference("text_begin", 0); EOL("Address"); - EmitDifference("text_end", 0, "text_begin", 0); EOL("Length"); + // Range 1 + EmitReference("text_begin", 0); EOL("Address"); + EmitDifference("text_end", 0, "text_begin", 0); EOL("Length"); - EmitInt32(0); EOL("EOM (1)"); - EmitInt32(0); EOL("EOM (2)"); - - O << "\n"; + EmitInt32(0); EOL("EOM (1)"); + EmitInt32(0); EOL("EOM (2)"); + + O << "\n"; + } + } +#endif } /// EmitDebugRanges - Emit visible names into a debug ranges section. @@ -1680,7 +1733,7 @@ const UniqueVector CUW = DebugInfo->getCompileUnits(); for (unsigned i = 1, N = CUW.size(); i <= N; ++i) { - DIE *Unit = NewCompileUnit(CUW[i]); + CompileUnit *Unit = NewCompileUnit(CUW[i], i); CompileUnits.push_back(Unit); } } @@ -1736,9 +1789,8 @@ , didInitial(false) , CompileUnits() , Abbreviations() -, GlobalTypes() -, GlobalEntities() , StringPool() +, DescToUnitMap() , DescToDieMap() , TypeToDieMap() , AddressSize(sizeof(int32_t)) @@ -1812,9 +1864,6 @@ // Emit info into a debug pubnames section. EmitDebugPubNames(); - // Emit info into a debug pubtypes section. - // EmitDebugPubTypes(); - // Emit info into a debug str section. EmitDebugStr(); From lattner at cs.uiuc.edu Mon Feb 27 14:09:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 14:09:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Message-ID: <200602272009.OAA15265@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcAsmPrinter.cpp updated: 1.55 -> 1.56 --- Log message: Don't print constant initializers, they may span lines now. --- Diffs of the changes: (+0 -2) SparcAsmPrinter.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp diff -u llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.55 llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.56 --- llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.55 Wed Feb 15 01:07:14 2006 +++ llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Mon Feb 27 14:09:23 2006 @@ -293,8 +293,6 @@ O << "\t.size " << name << "," << Size << "\n"; O << name << ":\t\t\t\t! "; WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); O << "\n"; EmitGlobalConstant(C); } From jlaskey at apple.com Mon Feb 27 14:37:54 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 14:37:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200602272037.OAA15689@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.32 -> 1.33 --- Log message: Partial enabling of functions. --- Diffs of the changes: (+1 -1) DwarfWriter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.32 llvm/lib/CodeGen/DwarfWriter.cpp:1.33 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.32 Mon Feb 27 11:27:12 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Mon Feb 27 14:37:42 2006 @@ -1208,7 +1208,7 @@ // FIXME - faking the type for the time being. DIE *Type = NewBasicType(Unit, Type::IntTy); - DIE *SubprogramDie = new DIE(DW_TAG_variable); + DIE *SubprogramDie = new DIE(DW_TAG_subprogram); SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name); SubprogramDie->AddUInt (DW_AT_decl_file, 0, FileID); SubprogramDie->AddUInt (DW_AT_decl_line, 0, Line); From natebegeman at mac.com Mon Feb 27 16:08:52 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 27 Feb 2006 16:08:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602272208.QAA17443@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.63 -> 1.64 --- Log message: readme updates --- Diffs of the changes: (+26 -21) README.txt | 47 ++++++++++++++++++++++++++--------------------- 1 files changed, 26 insertions(+), 21 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.63 llvm/lib/Target/PowerPC/README.txt:1.64 --- llvm/lib/Target/PowerPC/README.txt:1.63 Wed Feb 8 00:43:51 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon Feb 27 16:08:36 2006 @@ -52,7 +52,7 @@ as: xoris r0,r3,0x1234 - cmpwi cr0,r0,0x5678 + cmplwi cr0,r0,0x5678 beq cr0,L6 not: @@ -148,30 +148,35 @@ void AdjustBitfields(program* prog, unsigned int fmt1) { - unsigned int shift = 0; - unsigned int texCount = 0; - unsigned int i; - - for (i = 0; i < 8; i++) - { - prog->array[i].bitfields.field0 = texCount; - prog->array[i].bitfields.field1 = texCount + 1; - prog->array[i].bitfields.field2 = texCount + 2; - prog->array[i].bitfields.field3 = texCount + 3; - - texCount += (fmt1 >> shift) & 0x7; - shift += 3; - } + prog->array[0].bitfields.field0 = fmt1; + prog->array[0].bitfields.field1 = fmt1 + 1; } -In the loop above, the bitfield adds get generated as -(add (shl bitfield, C1), (shl C2, C1)) where C2 is 1, 2 or 3. +We currently generate: -Since the input to the (or and, and) is an (add) rather than a (shl), the shift -doesn't get folded into the rlwimi instruction. We should ideally see through -things like this, rather than forcing llvm to generate the equivalent +_AdjustBitfields: + lwz r2, 0(r3) + addi r5, r4, 1 + rlwinm r2, r2, 0, 0, 19 + rlwinm r5, r5, 6, 20, 25 + rlwimi r2, r4, 0, 26, 31 + or r2, r2, r5 + stw r2, 0(r3) + blr + +We should teach someone that or (rlwimi, rlwinm) with disjoint masks can be +turned into rlwimi (rlwimi) -(shl (add bitfield, C2), C1) with some kind of mask. +The better codegen would be: + +_AdjustBitfields: + lwz r0,0(r3) + rlwinm r4,r4,0,0xff + rlwimi r0,r4,0,26,31 + addi r4,r4,1 + rlwimi r0,r4,6,20,25 + stw r0,0(r3) + blr ===-------------------------------------------------------------------------=== From natebegeman at mac.com Mon Feb 27 16:09:44 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 27 Feb 2006 16:09:44 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.tests Message-ID: <200602272209.QAA17471@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.tests updated: 1.6 -> 1.7 --- Log message: tweak for SPEC --- Diffs of the changes: (+4 -0) Makefile.tests | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm-test/Makefile.tests diff -u llvm-test/Makefile.tests:1.6 llvm-test/Makefile.tests:1.7 --- llvm-test/Makefile.tests:1.6 Mon Jan 16 19:20:40 2006 +++ llvm-test/Makefile.tests Mon Feb 27 16:09:31 2006 @@ -60,6 +60,10 @@ Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES) -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@ -emit-llvm +# Compile from X.C to Output/X.ll +Output/%.ll: %.C $(LCC1XX) Output/.dir $(INCLUDES) + -$(LLVMGXX) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@ -emit-llvm + # LLVM Assemble from Output/X.ll to Output/X.bc. Output/X.ll must have come # from GCC output, so use GCCAS. # From natebegeman at mac.com Mon Feb 27 16:10:24 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 27 Feb 2006 16:10:24 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Makefile.multisrc Message-ID: <200602272210.QAA17495@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource: Makefile.multisrc updated: 1.51 -> 1.52 --- Log message: tweak for SPEC --- Diffs of the changes: (+3 -0) Makefile.multisrc | 3 +++ 1 files changed, 3 insertions(+) Index: llvm-test/MultiSource/Makefile.multisrc diff -u llvm-test/MultiSource/Makefile.multisrc:1.51 llvm-test/MultiSource/Makefile.multisrc:1.52 --- llvm-test/MultiSource/Makefile.multisrc:1.51 Fri Feb 17 18:02:32 2006 +++ llvm-test/MultiSource/Makefile.multisrc Mon Feb 27 16:10:13 2006 @@ -31,6 +31,9 @@ Output/%.o: %.c Output/.dir -$(CC) $(CPPFLAGS) $(CFLAGS) -O2 $(TARGET_CFLAGS) -c $< -o $@ +Output/%.o: %.C Output/.dir + -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_CFLAGS) -c $< -o $@ + Output/%.o: %.cpp Output/.dir -$(CC) $(CPPFLAGS) $(CXXFLAGS) -O2 $(TARGET_CFLAGS) -c $< -o $@ From natebegeman at mac.com Mon Feb 27 16:11:14 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 27 Feb 2006 16:11:14 -0600 Subject: [llvm-commits] CVS: llvm-test/External/SPEC/Makefile.spec Message-ID: <200602272211.QAA17517@zion.cs.uiuc.edu> Changes in directory llvm-test/External/SPEC: Makefile.spec updated: 1.52 -> 1.53 --- Log message: Allow people to override the default SPEC directory --- Diffs of the changes: (+11 -1) Makefile.spec | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletion(-) Index: llvm-test/External/SPEC/Makefile.spec diff -u llvm-test/External/SPEC/Makefile.spec:1.52 llvm-test/External/SPEC/Makefile.spec:1.53 --- llvm-test/External/SPEC/Makefile.spec:1.52 Fri Feb 24 13:04:54 2006 +++ llvm-test/External/SPEC/Makefile.spec Mon Feb 27 16:11:02 2006 @@ -18,11 +18,19 @@ # CURRENT_DIR := $(shell cd .; pwd) BENCH_NAME := $(subst $(shell cd .. ; pwd),,$(CURRENT_DIR)) -SPEC_SUBDIR := $(subst $(shell cd ../..; pwd),,$(CURRENT_DIR)) # Remove any leading /'s from the paths BENCH_NAME := $(patsubst /%,%,$(BENCH_NAME)) + +## SPEC_SUITEDIR - Allow SPEC configuration files to override "CINT2000" with +## something else. + +ifndef SPEC_SUITEDIR +SPEC_SUBDIR := $(subst $(shell cd ../..; pwd),,$(CURRENT_DIR)) SPEC_SUBDIR := $(patsubst /%,%,$(SPEC_SUBDIR)) +else +SPEC_SUBDIR := $(SPEC_SUITEDIR)/$(BENCH_NAME) +endif ifndef SPEC_BENCH_DIR SPEC_BENCH_DIR := $(SPEC_ROOT)/$(SPEC_SUBDIR) @@ -31,9 +39,11 @@ PROG := $(BENCH_NAME) ifndef Source Source := $(wildcard $(SPEC_BENCH_DIR)/src/*.c \ + $(SPEC_BENCH_DIR)/src/*.C \ $(SPEC_BENCH_DIR)/src/*.cc \ $(SPEC_BENCH_DIR)/src/*.cpp \ $(SPEC_BENCH_DIR)/src/*.f \ + $(SPEC_BENCH_DIR)/src/*.F \ $(SPEC_BENCH_DIR)/src/*.f90 \ $(SPEC_BENCH_DIR)/src/*.F90) endif From natebegeman at mac.com Mon Feb 27 16:11:47 2006 From: natebegeman at mac.com (Nate Begeman) Date: Mon, 27 Feb 2006 16:11:47 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.nagfortran Message-ID: <200602272211.QAA17531@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.nagfortran updated: 1.4 -> 1.5 --- Log message: Preprocess some kinds of fortran files --- Diffs of the changes: (+7 -1) Makefile.nagfortran | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm-test/Makefile.nagfortran diff -u llvm-test/Makefile.nagfortran:1.4 llvm-test/Makefile.nagfortran:1.5 --- llvm-test/Makefile.nagfortran:1.4 Fri Feb 24 13:11:45 2006 +++ llvm-test/Makefile.nagfortran Mon Feb 27 16:11:35 2006 @@ -31,15 +31,21 @@ clean:: rm -f $(patsubst %.f,%.c, $(filter %.f,$(Source))) \ + $(patsubst %.F,%.c, $(filter %.F,$(Source))) \ $(patsubst %.f90,%.c, $(filter %.f90,$(Source))) \ $(patsubst %.F90,%.c, $(filter %.F90,$(Source))) %.c: %.f $(F95) -w -S -O2 $< -o $@ $(NAGFORTRAN_FLAGS) +%.f: %.F + $(CPP) -x c $< -o - $(CPPFLAGS) -traditional-cpp | $(SED) '/^# /d' > $@ + %.c: %.f90 $(F95) -w -S -O2 $< -o $@ $(NAGFORTRAN_FLAGS) +%.f90: %.F90 + $(CPP) -x c $< -o - $(CPPFLAGS) -traditional-cpp | $(SED) '/^# /d' > $@ -CPPFLAGS = -I$(F95_DIR)/lib/NAGWare +CPPFLAGS += -I$(F95_DIR)/lib/NAGWare LDFLAGS += $(F95_DIR)/lib/NAGWare/quickfit.o -Xlinker -flat_namespace $(F95_DIR)/lib/NAGWare/libf97.dylib $(F95_DIR)/lib/NAGWare/libf96.a From jlaskey at apple.com Mon Feb 27 16:37:36 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 16:37:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/Dwarf.cpp Message-ID: <200602272237.QAA17935@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Dwarf.cpp updated: 1.1 -> 1.2 --- Log message: Qualify dwarf namespace inside llvm namespace. --- Diffs of the changes: (+4 -1) Dwarf.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Support/Dwarf.cpp diff -u llvm/lib/Support/Dwarf.cpp:1.1 llvm/lib/Support/Dwarf.cpp:1.2 --- llvm/lib/Support/Dwarf.cpp:1.1 Mon Feb 27 06:43:29 2006 +++ llvm/lib/Support/Dwarf.cpp Mon Feb 27 16:37:23 2006 @@ -15,6 +15,8 @@ #include +namespace llvm { + namespace dwarf { /// TagString - Return the string for the specified tag. @@ -568,5 +570,6 @@ return ""; } -} // End of namespace llvm. +} // End of namespace dwarf. +} // End of namespace llvm. From jlaskey at apple.com Mon Feb 27 16:37:37 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 16:37:37 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/Dwarf.h Message-ID: <200602272237.QAA17939@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: Dwarf.h updated: 1.2 -> 1.3 --- Log message: Qualify dwarf namespace inside llvm namespace. --- Diffs of the changes: (+4 -0) Dwarf.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/Support/Dwarf.h diff -u llvm/include/llvm/Support/Dwarf.h:1.2 llvm/include/llvm/Support/Dwarf.h:1.3 --- llvm/include/llvm/Support/Dwarf.h:1.2 Mon Feb 27 06:43:29 2006 +++ llvm/include/llvm/Support/Dwarf.h Mon Feb 27 16:37:23 2006 @@ -16,6 +16,8 @@ #ifndef LLVM_SUPPORT_DWARF_H #define LLVM_SUPPORT_DWARF_H +namespace llvm { + namespace dwarf { //===----------------------------------------------------------------------===// @@ -513,4 +515,6 @@ } // End of namespace dwarf +} // End of namespace llvm + #endif From jlaskey at apple.com Mon Feb 27 16:37:37 2006 From: jlaskey at apple.com (Jim Laskey) Date: Mon, 27 Feb 2006 16:37:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200602272237.QAA17943@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.33 -> 1.34 --- Log message: Qualify dwarf namespace inside llvm namespace. --- Diffs of the changes: (+1 -1) DwarfWriter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.33 llvm/lib/CodeGen/DwarfWriter.cpp:1.34 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.33 Mon Feb 27 14:37:42 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Mon Feb 27 16:37:23 2006 @@ -26,7 +26,7 @@ #include using namespace llvm; -using namespace dwarf; +using namespace llvm::dwarf; static cl::opt DwarfVerbose("dwarf-verbose", cl::Hidden, From lattner at cs.uiuc.edu Mon Feb 27 17:45:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 17:45:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602272345.RAA18761@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.173 -> 1.174 --- Log message: Add support for output memory constraints. --- Diffs of the changes: (+38 -7) SelectionDAGISel.cpp | 45 ++++++++++++++++++++++++++++++++++++++------- 1 files changed, 38 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.173 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.174 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.173 Thu Feb 23 20:52:40 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Feb 27 17:45:39 2006 @@ -1420,8 +1420,7 @@ assert(I.getType() != Type::VoidTy && "Bad inline asm!"); OpVT = TLI.getValueType(I.getType()); } else { - Value *CallOperand = I.getOperand(OpNum); - const Type *OpTy = CallOperand->getType(); + const Type *OpTy = I.getOperand(OpNum)->getType(); OpVT = TLI.getValueType(cast(OpTy)->getElementType()); OpNum++; // Consumes a call operand. } @@ -1479,6 +1478,40 @@ switch (Constraints[i].Type) { case InlineAsm::isOutput: { + TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; + if (ConstraintCode.size() == 1) // not a physreg name. + CTy = TLI.getConstraintType(ConstraintCode[0]); + + if (CTy == TargetLowering::C_Memory) { + // Memory output. + SDOperand InOperandVal = getValue(I.getOperand(OpNum)); + + // Check that the operand (the address to store to) isn't a float. + if (!MVT::isInteger(InOperandVal.getValueType())) + assert(0 && "MATCH FAIL!"); + + if (!Constraints[i].isIndirectOutput) + assert(0 && "MATCH FAIL!"); + + OpNum++; // Consumes a call operand. + + // Extend/truncate to the right pointer type if needed. + MVT::ValueType PtrType = TLI.getPointerTy(); + if (InOperandVal.getValueType() < PtrType) + InOperandVal = DAG.getNode(ISD::ZERO_EXTEND, PtrType, InOperandVal); + else if (InOperandVal.getValueType() > PtrType) + InOperandVal = DAG.getNode(ISD::TRUNCATE, PtrType, InOperandVal); + + // Add information to the INLINEASM node to know about this output. + unsigned ResOpType = 4/*MEM*/ | (1 << 3); + AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); + AsmNodeOperands.push_back(InOperandVal); + break; + } + + // Otherwise, this is a register output. + assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!"); + // If this is an early-clobber output, or if there is an input // constraint that matches this, we need to reserve the input register // so no other inputs allocate to it. @@ -1500,8 +1533,8 @@ assert(I.getType() != Type::VoidTy && "Bad inline asm!"); RetValRegs = Regs; } else { - Value *CallOperand = I.getOperand(OpNum); - IndirectStoresToEmit.push_back(std::make_pair(Regs, CallOperand)); + IndirectStoresToEmit.push_back(std::make_pair(Regs, + I.getOperand(OpNum))); OpNum++; // Consumes a call operand. } @@ -1511,10 +1544,8 @@ break; } case InlineAsm::isInput: { - Value *CallOperand = I.getOperand(OpNum); + SDOperand InOperandVal = getValue(I.getOperand(OpNum)); OpNum++; // Consumes a call operand. - - SDOperand InOperandVal = getValue(CallOperand); if (isdigit(ConstraintCode[0])) { // Matching constraint? // If this is required to match an output register we have already set, From lattner at cs.uiuc.edu Mon Feb 27 23:31:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 23:31:01 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/rem.ll Message-ID: <200602280531.XAA20479@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: rem.ll updated: 1.9 -> 1.10 --- Log message: new testcase --- Diffs of the changes: (+6 -2) rem.ll | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/test/Regression/Transforms/InstCombine/rem.ll diff -u llvm/test/Regression/Transforms/InstCombine/rem.ll:1.9 llvm/test/Regression/Transforms/InstCombine/rem.ll:1.10 --- llvm/test/Regression/Transforms/InstCombine/rem.ll:1.9 Sun Feb 5 01:52:47 2006 +++ llvm/test/Regression/Transforms/InstCombine/rem.ll Mon Feb 27 23:30:48 2006 @@ -1,6 +1,6 @@ ; This test makes sure that these instructions are properly eliminated. ; - +; RUN: llvm-as < %s | opt -instcombine -disable-output && ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep rem implementation @@ -10,7 +10,7 @@ ret int %B } -int %test2(int %A) { ; 0 % X = 0, we don't need ot preserve traps +int %test2(int %A) { ; 0 % X = 0, we don't need to preserve traps %B = rem int 0, %A ret int %B } @@ -38,3 +38,7 @@ ret uint %V } +int %test6(int %A) { + %B = rem int %A, 0 ;; undef + ret int %B +} From lattner at cs.uiuc.edu Mon Feb 27 23:30:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 23:30:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602280530.XAA20470@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.441 -> 1.442 --- Log message: Rearrange some code, fold "rem X, 0", implementing rem.ll:test6 --- Diffs of the changes: (+39 -38) InstructionCombining.cpp | 77 +++++++++++++++++++++++------------------------ 1 files changed, 39 insertions(+), 38 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.441 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.442 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.441 Sun Feb 26 20:38:23 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Feb 27 23:30:45 2006 @@ -1814,6 +1814,17 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + // 0 % X == 0, we don't need to preserve faults! + if (Constant *LHS = dyn_cast(Op0)) + if (LHS->isNullValue()) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + + if (isa(Op0)) // undef % X -> 0 + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + if (isa(Op1)) + return ReplaceInstUsesWith(I, Op1); // X % undef -> undef + if (I.getType()->isSigned()) { if (Value *RHSNeg = dyn_castNegVal(Op1)) if (!isa(RHSNeg) || @@ -1842,22 +1853,19 @@ } } - if (isa(Op0)) // undef % X -> 0 - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - if (isa(Op1)) - return ReplaceInstUsesWith(I, Op1); // X % undef -> undef - if (ConstantInt *RHS = dyn_cast(Op1)) { + // X % 0 == undef, we don't need to preserve faults! + if (RHS->equalsInt(0)) + return ReplaceInstUsesWith(I, UndefValue::get(I.getType())); + if (RHS->equalsInt(1)) // X % 1 == 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); // Check to see if this is an unsigned remainder with an exact power of 2, // if so, convert to a bitwise and. if (ConstantUInt *C = dyn_cast(RHS)) - if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero) - if (!(Val & (Val-1))) // Power of 2 - return BinaryOperator::createAnd(Op0, - ConstantUInt::get(I.getType(), Val-1)); + if (isPowerOf2_64(C->getValue())) + return BinaryOperator::createAnd(Op0, SubOne(C)); if (!RHS->isNullValue()) { if (SelectInst *SI = dyn_cast(Op0)) @@ -1869,35 +1877,6 @@ } } - // If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two, - // transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'. - if (SelectInst *SI = dyn_cast(Op1)) - if (ConstantUInt *STO = dyn_cast(SI->getOperand(1))) - if (ConstantUInt *SFO = dyn_cast(SI->getOperand(2))) { - if (STO->getValue() == 0) { // Couldn't be this argument. - I.setOperand(1, SFO); - return &I; - } else if (SFO->getValue() == 0) { - I.setOperand(1, STO); - return &I; - } - - if (!(STO->getValue() & (STO->getValue()-1)) && - !(SFO->getValue() & (SFO->getValue()-1))) { - Value *TrueAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0, - SubOne(STO), SI->getName()+".t"), I); - Value *FalseAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0, - SubOne(SFO), SI->getName()+".f"), I); - return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd); - } - } - - // 0 % X == 0, we don't need to preserve faults! - if (ConstantInt *LHS = dyn_cast(Op0)) - if (LHS->equalsInt(0)) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - - if (Instruction *RHSI = dyn_cast(I.getOperand(1))) { // Turn A % (C << N), where C is 2^k, into A & ((C << N)-1) [urem only]. if (I.getType()->isUnsigned() && @@ -1911,6 +1890,28 @@ return BinaryOperator::createAnd(Op0, Add); } } + + // If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two, + // transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'. + if (SelectInst *SI = dyn_cast(Op1)) + if (ConstantUInt *STO = dyn_cast(SI->getOperand(1))) + if (ConstantUInt *SFO = dyn_cast(SI->getOperand(2))) { + if (STO->getValue() == 0) { // Couldn't be this argument. + I.setOperand(1, SFO); + return &I; + } else if (SFO->getValue() == 0) { + I.setOperand(1, STO); + return &I; + } + + if (isPowerOf2_64(STO->getValue()) && isPowerOf2_64(SFO->getValue())){ + Value *TrueAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0, + SubOne(STO), SI->getName()+".t"), I); + Value *FalseAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0, + SubOne(SFO), SI->getName()+".f"), I); + return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd); + } + } } return 0; From lattner at cs.uiuc.edu Mon Feb 27 23:41:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 23:41:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602280541.XAA20559@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.442 -> 1.443 --- Log message: Simplify some code now that the RHS of a rem can't be 0 --- Diffs of the changes: (+6 -8) InstructionCombining.cpp | 14 ++++++-------- 1 files changed, 6 insertions(+), 8 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.442 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.443 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.442 Mon Feb 27 23:30:45 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Feb 27 23:40:55 2006 @@ -1867,14 +1867,12 @@ if (isPowerOf2_64(C->getValue())) return BinaryOperator::createAnd(Op0, SubOne(C)); - if (!RHS->isNullValue()) { - if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldOpIntoSelect(I, SI, this)) - return R; - if (isa(Op0)) - if (Instruction *NV = FoldOpIntoPhi(I)) - return NV; - } + if (SelectInst *SI = dyn_cast(Op0)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) + return R; + if (isa(Op0)) + if (Instruction *NV = FoldOpIntoPhi(I)) + return NV; } if (Instruction *RHSI = dyn_cast(I.getOperand(1))) { From lattner at cs.uiuc.edu Mon Feb 27 23:49:09 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 23:49:09 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/rem.ll Message-ID: <200602280549.XAA20652@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: rem.ll updated: 1.10 -> 1.11 --- Log message: new testcases for PR712: http://llvm.cs.uiuc.edu/PR712 --- Diffs of the changes: (+18 -0) rem.ll | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/rem.ll diff -u llvm/test/Regression/Transforms/InstCombine/rem.ll:1.10 llvm/test/Regression/Transforms/InstCombine/rem.ll:1.11 --- llvm/test/Regression/Transforms/InstCombine/rem.ll:1.10 Mon Feb 27 23:30:48 2006 +++ llvm/test/Regression/Transforms/InstCombine/rem.ll Mon Feb 27 23:48:56 2006 @@ -42,3 +42,21 @@ %B = rem int %A, 0 ;; undef ret int %B } + +int %test7(int %A) { + %B = mul int %A, 26 + %C = rem int %B, 13 + ret int %C +} + +int %test8(int %A) { + %B = shl int %A, ubyte 4 + %C = rem int %B, 8 + ret int %C +} + +uint %test9(uint %A) { + %B = mul uint %A, 124 + %C = rem uint %B, 62 + ret uint %C +} From lattner at cs.uiuc.edu Mon Feb 27 23:49:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 27 Feb 2006 23:49:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602280549.XAA20662@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.443 -> 1.444 --- Log message: Implement rem.ll:test[7-9] and PR712: http://llvm.cs.uiuc.edu/PR712 --- Diffs of the changes: (+22 -6) InstructionCombining.cpp | 28 ++++++++++++++++++++++------ 1 files changed, 22 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.443 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.444 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.443 Mon Feb 27 23:40:55 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Feb 27 23:49:21 2006 @@ -1867,12 +1867,28 @@ if (isPowerOf2_64(C->getValue())) return BinaryOperator::createAnd(Op0, SubOne(C)); - if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldOpIntoSelect(I, SI, this)) - return R; - if (isa(Op0)) - if (Instruction *NV = FoldOpIntoPhi(I)) - return NV; + if (Instruction *Op0I = dyn_cast(Op0)) { + if (SelectInst *SI = dyn_cast(Op0I)) { + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) + return R; + } else if (isa(Op0I)) { + if (Instruction *NV = FoldOpIntoPhi(I)) + return NV; + } else if (Op0I->getOpcode() == Instruction::Mul) { + // X*C1%C2 --> 0 iff C1%C2 == 0 + if (ConstantInt *MulRHS = dyn_cast(Op0I->getOperand(1))) { + if (ConstantExpr::getRem(MulRHS, RHS)->isNullValue()) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + } + } else if (Op0I->getOpcode() == Instruction::Shl) { + // (X< 0 iff (1<(Op0I->getOperand(1))) { + ShRHS = ConstantExpr::getShl(ConstantInt::get(I.getType(), 1), ShRHS); + if (ConstantExpr::getRem(ShRHS, RHS)->isNullValue()) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + } + } + } } if (Instruction *RHSI = dyn_cast(I.getOperand(1))) { From lattner at cs.uiuc.edu Tue Feb 28 00:23:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 00:23:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602280623.AAA20859@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.110 -> 1.111 --- Log message: fold (sra (sra x, c1), c2) -> (sra x, c1+c2) --- Diffs of the changes: (+11 -3) DAGCombiner.cpp | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.110 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.111 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.110 Sun Feb 26 18:39:31 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 00:23:04 2006 @@ -23,9 +23,6 @@ // FIXME: mul (x, const) -> shifts + adds // FIXME: undef values // FIXME: make truncate see through SIGN_EXTEND and AND -// FIXME: (sra (sra x, c1), c2) -> (sra x, c1+c2) -// FIXME: verify that getNode can't return extends with an operand whose type -// is >= to that of the extend. // FIXME: divide by zero is currently left unfolded. do we want to turn this // into an undef? // FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false @@ -1367,6 +1364,17 @@ return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), DAG.getValueType(EVT)); } + + // fold (sra (sra x, c1), c2) -> (sra x, c1+c2) + if (N1C && N0.getOpcode() == ISD::SRA) { + if (ConstantSDNode *C1 = dyn_cast(N0.getOperand(1))) { + unsigned Sum = N1C->getValue() + C1->getValue(); + if (Sum >= MVT::getSizeInBits(VT)) Sum = MVT::getSizeInBits(VT)-1; + return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), + DAG.getConstant(Sum, N1C->getValueType(0))); + } + } + // If the sign bit is known to be zero, switch this to a SRL. if (TLI.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT))) return DAG.getNode(ISD::SRL, VT, N0, N1); From lattner at cs.uiuc.edu Tue Feb 28 00:35:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 00:35:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602280635.AAA20983@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.111 -> 1.112 --- Log message: Fold "and (LOAD P), 255" -> zextload. This allows us to compile: unsigned foo3(unsigned *P) { return *P & 255; } as: _foo3: lbz r3, 3(r3) blr instead of: _foo3: lwz r2, 0(r3) rlwinm r3, r2, 0, 24, 31 blr and: unsigned short foo2(float a) { return a; } as: _foo2: fctiwz f0, f1 stfd f0, -8(r1) lhz r3, -2(r1) blr instead of: _foo2: fctiwz f0, f1 stfd f0, -8(r1) lwz r2, -4(r1) rlwinm r3, r2, 0, 16, 31 blr --- Diffs of the changes: (+33 -0) DAGCombiner.cpp | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.111 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.112 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.111 Tue Feb 28 00:23:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 00:35:35 2006 @@ -1042,6 +1042,39 @@ return SDOperand(); } } + + // fold (and (load x), 255) -> (zextload x) + if (N1C && N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) { + MVT::ValueType EVT; + if (N1C->getValue() == 255) + EVT = MVT::i8; + else if (N1C->getValue() == 65535) + EVT = MVT::i16; + else if (N1C->getValue() == ~0U) + EVT = MVT::i32; + else + EVT = MVT::Other; + if (EVT != MVT::Other) { + assert(MVT::getSizeInBits(VT) > MVT::getSizeInBits(EVT) && + "Cannot zext to larger type!"); + MVT::ValueType PtrType = N0.getOperand(1).getValueType(); + // For big endian targets, we need to add an offset to the pointer to load + // the correct bytes. For little endian systems, we merely need to read + // fewer bytes from the same pointer. + uint64_t PtrOff = (MVT::getSizeInBits(VT) - MVT::getSizeInBits(EVT)) / 8; + SDOperand NewPtr = TLI.isLittleEndian() ? N0.getOperand(1) : + DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), + DAG.getConstant(PtrOff, PtrType)); + WorkList.push_back(NewPtr.Val); + SDOperand Load = + DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), NewPtr, + N0.getOperand(2), EVT); + WorkList.push_back(N); + CombineTo(N0.Val, Load, Load.getValue(1)); + return SDOperand(); + } + } + return SDOperand(); } From lattner at cs.uiuc.edu Tue Feb 28 00:36:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 00:36:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602280636.AAA21028@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.64 -> 1.65 --- Log message: remove implemented item --- Diffs of the changes: (+0 -17) README.txt | 17 ----------------- 1 files changed, 17 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.64 llvm/lib/Target/PowerPC/README.txt:1.65 --- llvm/lib/Target/PowerPC/README.txt:1.64 Mon Feb 27 16:08:36 2006 +++ llvm/lib/Target/PowerPC/README.txt Tue Feb 28 00:36:04 2006 @@ -11,23 +11,6 @@ ===-------------------------------------------------------------------------=== -unsigned short foo(float a) { return a; } -should be: -_foo: - fctiwz f0,f1 - stfd f0,-8(r1) - lhz r3,-2(r1) - blr -not: -_foo: - fctiwz f0, f1 - stfd f0, -8(r1) - lwz r2, -4(r1) - rlwinm r3, r2, 0, 16, 31 - blr - -===-------------------------------------------------------------------------=== - Support 'update' load/store instructions. These are cracked on the G5, but are still a codesize win. From lattner at cs.uiuc.edu Tue Feb 28 00:49:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 00:49:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602280649.AAA21083@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.112 -> 1.113 --- Log message: Compile: unsigned foo4(unsigned short *P) { return *P & 255; } unsigned foo5(short *P) { return *P & 255; } to: _foo4: lbz r3,1(r3) blr _foo5: lbz r3,1(r3) blr not: _foo4: lhz r2, 0(r3) rlwinm r3, r2, 0, 24, 31 blr _foo5: lhz r2, 0(r3) rlwinm r3, r2, 0, 24, 31 blr --- Diffs of the changes: (+17 -10) DAGCombiner.cpp | 27 +++++++++++++++++---------- 1 files changed, 17 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.112 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.113 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.112 Tue Feb 28 00:35:35 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 00:49:37 2006 @@ -1043,9 +1043,13 @@ } } - // fold (and (load x), 255) -> (zextload x) - if (N1C && N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) { - MVT::ValueType EVT; + // fold (and (load x), 255) -> (zextload x, i8) + // fold (and (extload x, i16), 255) -> (zextload x, i8) + if (N1C && + (N0.getOpcode() == ISD::LOAD || N0.getOpcode() == ISD::EXTLOAD || + N0.getOpcode() == ISD::ZEXTLOAD) && + N0.hasOneUse()) { + MVT::ValueType EVT, LoadedVT; if (N1C->getValue() == 255) EVT = MVT::i8; else if (N1C->getValue() == 65535) @@ -1054,17 +1058,20 @@ EVT = MVT::i32; else EVT = MVT::Other; - if (EVT != MVT::Other) { - assert(MVT::getSizeInBits(VT) > MVT::getSizeInBits(EVT) && - "Cannot zext to larger type!"); + + LoadedVT = N0.getOpcode() == ISD::LOAD ? VT : + cast(N0.getOperand(3))->getVT(); + if (EVT != MVT::Other && LoadedVT > EVT) { MVT::ValueType PtrType = N0.getOperand(1).getValueType(); // For big endian targets, we need to add an offset to the pointer to load // the correct bytes. For little endian systems, we merely need to read // fewer bytes from the same pointer. - uint64_t PtrOff = (MVT::getSizeInBits(VT) - MVT::getSizeInBits(EVT)) / 8; - SDOperand NewPtr = TLI.isLittleEndian() ? N0.getOperand(1) : - DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), - DAG.getConstant(PtrOff, PtrType)); + unsigned PtrOff = + (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8; + SDOperand NewPtr = N0.getOperand(1); + if (!TLI.isLittleEndian()) + NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr, + DAG.getConstant(PtrOff, PtrType)); WorkList.push_back(NewPtr.Val); SDOperand Load = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), NewPtr, From lattner at cs.uiuc.edu Tue Feb 28 00:54:31 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 00:54:31 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Message-ID: <200602280654.AAA21141@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: small-arguments.ll updated: 1.3 -> 1.4 --- Log message: new testcases --- Diffs of the changes: (+30 -1) small-arguments.ll | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll diff -u llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.3 llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.4 --- llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll:1.3 Thu Sep 1 19:13:56 2005 +++ llvm/test/Regression/CodeGen/PowerPC/small-arguments.ll Tue Feb 28 00:54:19 2006 @@ -1,5 +1,9 @@ + +; RUN: llvm-as < %s | llc -march=ppc32 && ; RUN: llvm-as < %s | llc -march=ppc32 | not grep 'extsh\|rlwinm' +declare short %foo() + int %test1(short %X) { %Y = cast short %X to int ;; dead ret int %Y @@ -23,4 +27,29 @@ ret void } -declare short %foo() +uint %test4(ushort* %P) { + %tmp.1 = load ushort* %P + %tmp.2 = cast ushort %tmp.1 to uint + %tmp.3 = and uint %tmp.2, 255 + ret uint %tmp.3 +} + +uint %test5(short* %P) { + %tmp.1 = load short* %P + %tmp.2 = cast short %tmp.1 to ushort + %tmp.3 = cast ushort %tmp.2 to uint + %tmp.4 = and uint %tmp.3, 255 + ret uint %tmp.4 +} + +uint %test6(uint* %P) { + %tmp.1 = load uint* %P + %tmp.2 = and uint %tmp.1, 255 + ret uint %tmp.2 +} + +ushort %test7(float %a) { + %tmp.1 = cast float %a to ushort + ret ushort %tmp.1 +} + From lattner at cs.uiuc.edu Tue Feb 28 01:08:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 01:08:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.td PPCSubtarget.h Message-ID: <200602280708.BAA21251@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.td updated: 1.11 -> 1.12 PPCSubtarget.h updated: 1.12 -> 1.13 --- Log message: Add a subtarget feature for the stfiwx instruction. I know the G5 has it, but I don't know what other PPC impls do. If someone could update the proc table, I would appreciate it :) --- Diffs of the changes: (+6 -2) PPC.td | 6 ++++-- PPCSubtarget.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.td diff -u llvm/lib/Target/PowerPC/PPC.td:1.11 llvm/lib/Target/PowerPC/PPC.td:1.12 --- llvm/lib/Target/PowerPC/PPC.td:1.11 Fri Jan 27 02:09:42 2006 +++ llvm/lib/Target/PowerPC/PPC.td Tue Feb 28 01:08:22 2006 @@ -29,6 +29,8 @@ "Enable GPUL instructions">; def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true", "Enable the fsqrt instruction">; +def FeatureSTFIWX : SubtargetFeature<"stfiwx","HasSTFIWX", "true", + "Enable the stfiwx instruction">; //===----------------------------------------------------------------------===// // Register File Description @@ -58,10 +60,10 @@ def : Processor<"g4+", G4PlusItineraries, [FeatureAltivec]>; def : Processor<"750", G3Itineraries, []>; def : Processor<"970", G5Itineraries, - [FeatureAltivec, FeatureGPUL, FeatureFSqrt, + [FeatureAltivec, FeatureGPUL, FeatureFSqrt, FeatureSTFIWX, Feature64Bit /*, Feature64BitRegs */]>; def : Processor<"g5", G5Itineraries, - [FeatureAltivec, FeatureGPUL, FeatureFSqrt, + [FeatureAltivec, FeatureGPUL, FeatureFSqrt, FeatureSTFIWX, Feature64Bit /*, Feature64BitRegs */]>; Index: llvm/lib/Target/PowerPC/PPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PPCSubtarget.h:1.12 llvm/lib/Target/PowerPC/PPCSubtarget.h:1.13 --- llvm/lib/Target/PowerPC/PPCSubtarget.h:1.12 Tue Nov 1 14:07:00 2005 +++ llvm/lib/Target/PowerPC/PPCSubtarget.h Tue Feb 28 01:08:22 2006 @@ -37,6 +37,7 @@ bool Has64BitRegs; bool HasAltivec; bool HasFSQRT; + bool HasSTFIWX; bool IsAIX; bool IsDarwin; public: @@ -60,6 +61,7 @@ bool hasFSQRT() const { return HasFSQRT; } + bool hasSTFIWX() const { return HasSTFIWX; } bool has64BitRegs() const { return Has64BitRegs; } bool hasAltivec() const { return HasAltivec; } From lattner at cs.uiuc.edu Tue Feb 28 10:40:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 10:40:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/overlap-shift.ll Message-ID: <200602281640.KAA01289@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: overlap-shift.ll updated: 1.2 -> 1.3 --- Log message: evan's recent x86 isel improvements have fixed this, though not in the way originally envisioned :) --- Diffs of the changes: (+0 -3) overlap-shift.ll | 3 --- 1 files changed, 3 deletions(-) Index: llvm/test/Regression/CodeGen/X86/overlap-shift.ll diff -u llvm/test/Regression/CodeGen/X86/overlap-shift.ll:1.2 llvm/test/Regression/CodeGen/X86/overlap-shift.ll:1.3 --- llvm/test/Regression/CodeGen/X86/overlap-shift.ll:1.2 Sun Jan 2 13:01:33 2005 +++ llvm/test/Regression/CodeGen/X86/overlap-shift.ll Tue Feb 28 10:39:56 2006 @@ -8,9 +8,6 @@ ; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel | not grep 'mov %E.X, %E.X' -; FIXME: We need live variable information about flags to do this xform safely. :( -; XFAIL: * - %G = external global int int %test1(int %X) { From natebegeman at mac.com Tue Feb 28 12:09:06 2006 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 28 Feb 2006 12:09:06 -0600 Subject: [llvm-commits] CVS: llvm-test/filepp Makefile.nagfortran Message-ID: <200602281809.MAA10470@zion.cs.uiuc.edu> Changes in directory llvm-test: filepp added (r1.1) Makefile.nagfortran updated: 1.5 -> 1.6 --- Log message: Add support for "preprocessed FORTRAN" source *shudder* --- Diffs of the changes: (+2735 -2) Makefile.nagfortran | 4 filepp | 2733 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2735 insertions(+), 2 deletions(-) Index: llvm-test/filepp diff -c /dev/null llvm-test/filepp:1.1 *** /dev/null Tue Feb 28 12:09:04 2006 --- llvm-test/filepp Tue Feb 28 12:08:54 2006 *************** *** 0 **** --- 1,2733 ---- + #!/usr/bin/perl -w + ######################################################################## + # + # filepp is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; see the file COPYING. If not, write to + # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + # + ######################################################################## + # + # Project : File Preprocessor + # Filename : $RCSfile: filepp,v $ + # Author : $Author: sampo $ + # Maintainer : Darren Miller: darren at cabaret.demon.co.uk + # File version : $Revision: 1.1 $ + # Last changed : $Date: 2006/02/28 18:08:54 $ + # Description : Main program + # Licence : GNU copyleft + # + ######################################################################## + + package Filepp; + + use strict "vars"; + use strict "subs"; + # Used to all filepp to work with any char, not just ascii, + # feel free to remove this if it causes you problems + use bytes; + + # version number of program + my $VERSION = '1.7.1'; + + # list of paths to search for modules, normal Perl list + module dir + push(@INC, "/usr/local/share/filepp/modules"); + + # index of keywords supported and functions to deal with them + my %Keywords = ( + 'comment' => \&Comment, + 'define' => \&Define, + 'elif' => \&Elif, + 'else' => \&Else, + 'endif' => \&Endif, + 'error' => \&Error, + 'if' => \&If, + 'ifdef' => \&Ifdef, + 'ifndef' => \&Ifndef, + 'include' => \&Include, + 'pragma' => \&Pragma, + 'undef' => \&Undef, + 'warning' => \&Warning + ); + + # set of functions which process the file in the Parse routine. + # Processors are functions which take in a line and return the processed line. + # Note: this is done as a string rather than pointer to a function because + # it makes list easier to modify/remove from/print. + my @Processors = ( "Filepp::ParseKeywords", "Filepp::ReplaceDefines" ); + # processor types say what the processor should be run on: choice is: + # 0: Everything (default) + # 1: Full lines only (lines originating from Parse function) + # 2: Part lines only (lines originating from within keywords, eg: + # #if "condition", "condition" is a part line) + my %ProcessorTypes = ( + 'Filepp::ParseKeywords' => 1, + 'Filepp::ReplaceDefines' => 0 + ); + + # functions to run each time a new base input file is opened or closed + my @OpenInputFuncs = (); + my @CloseInputFuncs = (); + + # functions to run each time a new output file is opened or closed + my @OpenOutputFuncs = (); + my @CloseOutputFuncs = (); + + # safe mode is for the paranoid, when enabled turns off #pragma filepp, + # enabled by default + my $safe_mode = 0; + + # test for shebang mode, used for "filepp script", ie. executable file with + # "#!/usr/bin/perl /usr/local/bin/filepp" at the top + my $shebang = 1; + + # allow $keywordchar, $contchar, $optlineendchar and $macroprefix + # to be perl regexps + my $charperlre = 0; + + # character(s) which prefix environment variables - defaults to shell-style '$' + my $envchar = "\$"; + + # boolean determining whether line continuation is implicit if there are more + # open brackets than close brackets on a line + # disabled by default + my $parselineend = \&Filepp::ParseLineEnd; + + # character(s) which replace continuation char(s) - defaults to C-style nothing + my $contrepchar = ""; + + # character(s) which prefix keywords - defaults to C-style '#' + my $keywordchar; + if($charperlre) { $keywordchar = "\#"; } + else { $keywordchar = "\Q#\E"; } + + # character(s) which signifies continuation of a line - defaults to C-style '\' + my $contchar; + if($charperlre) { $contchar = "\\\\"; } + else { $contchar = "\Q\\\E"; } + + # character(s) which optionally signifies the end of a line - + # defaults to empty string '' + my $optlineendchar = ""; + + # character(s) which prefix macros - defaults to nothing + my $macroprefix = ""; + + # flag to use macro prefix in keywords (on by default) + my $macroprefixinkeywords = 1; + + # check if macros must occur as words when replacing, set this to '\b' if + # you prefer cpp style behaviour as default + my $bound = ''; + + # number of line currently being parsed (int) + my $line = 0; + + # file currently being parsed + my $file = ""; + + # list of input files + my @Inputfiles; + + # list of files to include macros from + my @Imacrofiles; + + # flag to control when output is written + my $output = 1; + + # name of outputfile - defaults to STDOUT + my $outputfile = ""; + + # overwrite mode - automatically overwrites old file with new file + my $overwrite = 0; + + # overwrite conversion mode - conversion from input filename to output filename + my $overwriteconv = ""; + + # list of keywords which have "if" functionality + my %Ifwords = ('if', '', + 'ifdef', '', + 'ifndef', ''); + + # list of keywords which have "else" functionality + my %Elsewords = ('else', '', + 'elif', ''); + + # list of keywords which have "endif" functionality + my %Endifwords = ('endif', ''); + + # current level of include files + my $include_level = -1; + + # suppress blank lines in header files (indexed by include level) + my $blanksuppopt = 0; + my @blanksupp; + # try to keep same number lines in output file as input file + my $preserveblank = 0; + + # counter of recursion level for detecting recursive macros + my $recurse_level = -1; + + # debugging info, 1=on, 0=off + my $debug = 0; + # send debugging info to stdout rather than stderr + my $debugstdout = 0; + # debug prefix character or string + my $debugprefix = ""; + # debug postfix character or string + my $debugpostfix = "\n"; + + # hash of macros defined - standard ones already included + my %Defines = ( + '__BASE_FILE__' => "", + '__DATE__' => "", + '__FILEPP_INPUT__' => "Generated automatically from __BASE_FILE__ by filepp", + '__FILE__' => $file, + '__INCLUDE_LEVEL__' => $include_level, + '__ISO_DATE__' => "", + '__LINE__' => $line, + '__NEWLINE__' => "\n", + '__NULL__' => "", + '__TAB__' => "\t", + '__TIME__' => "", + '__VERSION__' => $VERSION + ); + # hash of first chars in each macro + my %DefineLookup; + # length of longest and shortest define + my ($defmax, $defmin); + GenerateDefinesKeys(); + + # set default values for date and time + { + # conversions of month number into letters (0-11) + my @MonthChars = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); + #prepare standard defines + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isbst) = + localtime(time()); + $year += 1900; + $sec = sprintf("%02d", $sec); + $min = sprintf("%02d", $min); + $hour = sprintf("%02d", $hour); + $mday = sprintf("%02d", $mday); + $mon = sprintf("%02d", $mon); + Redefine("__TIME__", $hour.":".$min.":".$sec); + Redefine("__DATE__", $MonthChars[$mon]." ".$mday." ".$year); + $mon = sprintf("%02d", ++$mon); + Redefine("__ISO_DATE__", $year."-".$mon."-".$mday); + } + + # hash table for arguments to macros which need them + my %DefinesArgs = (); + + # hash table for functions which macros should call (if any) + my %DefinesFuncs = (); + + # eat-trailing-whitespace flag for each macro + my %EatTrail = (); + + # list of include paths + my @IncludePaths; + + # help string + my $usage = "filepp: generic file preprocessor, version ".$VERSION." + usage: filepp [options] inputfile(s) + options: + -b\t\tsuppress blank lines from include files + -c\t\tread input from STDIN instead of file + -Dmacro[=defn]\tdefine macros (same as #define) + -d\t\tprint debugging information + -dd\t\tprint verbose debugging information + -dl\t\tprint some (light) debugging information + -dpre char\tprefix all debugging information with char + -dpost char\tpostfix all debugging information with char, defaults to newline + -ds\t\tsend debugging info to stdout rather than stderr + -e\t\tdefine all environment variables as macros + -ec char\tset environment variable prefix char to \"char\" (default \$) + -ecn\t\tset environment variable prefix char to nothing (default \$) + -h\t\tprint this help message + -Idir\t\tdirectory to search for include files + -imacros file\tread in macros from file, but discard rest of file + -k\t\tturn off parsing of all keywords, just macro expansion is done + -kc char\tset keyword prefix char to \"char\" (defaults to #) + -lc char\tset line continuation character to \"char\" (defaults to \\) + -lec char\tset optional keyword line end char to \"char\" + -lr char\tset line continuation replacement character to \"char\" + -lrn\t\tset line continuation replacement character to newline + -m module\tload module + -mp char\tprefix all macros with \"char\" (defaults to no prefix) + -mpnk\t\tdo not use macro prefix char in keywords + -Mdir\t\tdirectory to search for filepp modules + -o output\tname of output file (defaults to stdout) + -ov\t\toverwrite mode - output file will overwrite input file + -ovc IN=OUT\toutput file(s) will have be input file(s) with IN conveted to OUT + -pb\t\tpreseve blank lines in output that would normally be removed + -s\t\trun in safe mode (turns off pragma keyword) + -re\t\ttreat keyword and macro prefixes and line cont chars as reg exps + -u\t\tundefine all predefined macros + -v\t\tprint version and exit + -w\t\tturn on word boundaries when replacing macros + all other arguments are assumed to be input files + "; + + + ############################################################################## + # SetDebug - controls debugging level + ############################################################################## + sub SetDebug + { + $debug = shift; + Debug("Debugging level set to $debug", 1); + } + + + ############################################################################## + # Debugging info + ############################################################################## + sub Debug + { + # print nothing if not debugging + if($debug == 0) { return; } + my $msg = shift; + my $level = 1; + # check if level has been provided + if($#_ > -1) { $level = shift; } + if($level <= $debug) { + # if currently parsing a file show filename and line number + if($file ne "" && $line > 0) { + $msg = $file.":".$line.": ".$msg; + } + # else show program name + else { $msg = "filepp: ".$msg; } + if($debugstdout) { + print(STDOUT $debugprefix.$msg.$debugpostfix); + } + else { + print(STDERR $debugprefix.$msg.$debugpostfix); + } + } + } + + + ############################################################################## + # Standard error handler. + # #error msg - print error message "msg" and exit + ############################################################################## + sub Error + { + my $msg = shift; + # close and delete output file if created + close(OUTPUT); + if($outputfile ne "-") { # output is not stdout + my $inputfile; + my $found = 0; + # do paranoid check to make sure we are not deleting an input file + foreach $inputfile (@Inputfiles) { + if($outputfile eq $inputfile) { $found = 1; last; } + } + # delete output file + if($found == 0) { unlink($outputfile); } + } + # print error message + $debug = 1; + Debug($msg, 0); + exit(1); + } + + + ############################################################################## + # SafeMode - turns safe mode on + ############################################################################## + sub SafeMode + { + $safe_mode = 1; + Debug("Filepp safe mode enabled", 2); + } + + + ############################################################################## + # CleanStart($sline) - strip leading whitespace from start of $sline. + ############################################################################## + sub CleanStart + { + my $sline = shift; + for($sline) { + # '^' = start of line, '\s+' means all whitespace, replace with nothing + s/^\s+//; + } + return $sline; + } + + + ############################################################################## + # Strip($sline, $char, $level) - strip $char's from start and end of $sline + # removes up to $level $char's from start and end of line, it is not an + # error if $level chars do not exist at the start or end of line + ############################################################################## + sub Strip + { + my $sline = shift; + my $char = shift; + my $level = shift; + # strip leading chars from line + $sline =~ s/\A([$char]{0,$level})//g; + # strip trailing chars from line + $sline =~ s/([$char]{0,$level})\Z//g; + return $sline; + } + + + ############################################################################## + # SetMacroPrefix $string - prefixs all macros with $string + ############################################################################## + sub SetMacroPrefix + { + $macroprefix = shift; + # make sure prefix will not be treated as a Perl regular expression + if(!$charperlre) { $macroprefix = "\Q$macroprefix\E"; } + Debug("Setting macro prefix to <".$macroprefix.">", 2); + } + + + ############################################################################## + # SetKeywordchar $string - sets the first char(s) of each keyword to + # something other than "#" + ############################################################################## + sub SetKeywordchar + { + $keywordchar = shift; + # make sure char will not be treated as a Perl regular expression + if(!$charperlre) { $keywordchar = "\Q$keywordchar\E"; } + Debug("Setting keyword prefix character to <".$keywordchar.">", 2); + } + + ############################################################################## + # GetKeywordchar - returns the current keywordchar + ############################################################################## + sub GetKeywordchar + { + return $keywordchar; + } + + + ############################################################################## + # SetContchar $string - sets the line continuation char to something other + # than "\" + ############################################################################## + sub SetContchar + { + $contchar = shift; + # make sure char will not be treated as a Perl regular expression + if(!$charperlre) { $contchar = "\Q$contchar\E"; } + Debug("Setting line continuation character to <".$contchar.">", 2); + } + + + ############################################################################## + # SetContrepchar $string - sets the replace of the line continuation char to + # something other than "" + ############################################################################## + sub SetContrepchar + { + $contrepchar = shift; + Debug("Setting line continuation replacement character to <".$contrepchar.">", 2); + } + + + ############################################################################## + # SetOptLineEndchar $string - sets the optional line end char to something + # other than "" + ############################################################################## + sub SetOptLineEndchar + { + $optlineendchar = shift; + # make sure char will not be treated as a Perl regular expression + if(!$charperlre) { $optlineendchar = "\Q$optlineendchar\E"; } + Debug("Setting optional line end character to <".$optlineendchar.">", 2); + } + + + ############################################################################## + # SetEnvchar $string - sets the first char(s) of each defined environment + # variable to $string - NOTE: change only takes effect when DefineEnv run + ############################################################################## + sub SetEnvchar + { + $envchar = shift; + Debug("Setting environment variable prefix character to <".$envchar.">",2); + } + + ############################################################################## + # RunProcessors $string, $calledfrom + # run the current processing chain on the string + # $string is the string to be processed and should be returned by the processor + # $calledfrom says where the processors are called from, the choice is: + # + # 0 or default: Part line (from within a keyword) - if called recursively + # runs all processors AFTER current processor, then continues with processing. + # This is used when a keyword want to run all remaining processors on a line + # before doing its keyword task. + # + # 1: Full line (from Parse function) - if called recursively runs all + # processors BEFORE current processor, then continues with processing + # + # 2: Part line (from within a keyword) - if called recursively runs all + # processors BEFORE current processor, then continues with processing. + # This is used when keywords are using text taken from somewhere other than + # the current line, this text needs to go through the same processors as + # the current line has been through so it can "catch up" (eg: regexp.pm). + # + ############################################################################## + my @Running; + my @Currentproc; + sub RunProcessors + { + my $string = shift; + my $calledfrom = 0; + if($#_ > -1) { $calledfrom = shift; } + my $i; + + # turn off macoprefix if in a keyword + my $tmpprefix = ""; + if($calledfrom != 1 && $macroprefixinkeywords == 0) { + $tmpprefix = $macroprefix; + $macroprefix = ""; + } + + # These tests are done to make RunProcessors recursion safe. + # If RunProcessors is called from with a function that was itself called + # by RunProcessors, then the second calling of RunProcessors will only + # execute the processors before the currently running processor in the + # chain. + my $recursing = 0; + my $firstproc = 0; + my $lastproc = $#Processors; + if($Running[$include_level]) { + if($calledfrom == 0) { + $firstproc = $Currentproc[$include_level] + 1; + } + else { + $lastproc = $Currentproc[$include_level] - 1; + } + $recursing = 1; + } + else { $Running[$include_level] = 1; } + + for($i = $firstproc; $i <= $lastproc; $i++) { + if(!$recursing) { $Currentproc[$include_level] = $i; } + # called from anywhere (default) + if($ProcessorTypes{$Processors[$i]} == 0 || + # called from keyword (part lines only - within keywords) + (($calledfrom == 0 || $calledfrom == 2) && + $ProcessorTypes{$Processors[$i]} == 2) || + # called from Parse function (whole lines only) + ($calledfrom == 1 && $ProcessorTypes{$Processors[$i]} == 1)) { + # run processor + # Debug("Running processor $Processors[$i] on \"$string\"", 2); + $string = $Processors[$i]->($string); + } + # check that no processors have been deleted (bigdef.pm) + if($lastproc > $#Processors) { $lastproc = $#Processors; } + } + + if(!$recursing) { $Running[$include_level] = 0; } + + # return macro prefix to its former glory + if($calledfrom != 1 && $macroprefixinkeywords == 0) { + $macroprefix = $tmpprefix; + } + + return $string; + } + + ############################################################################## + # PrintProcessors + # print the current processing chain + ############################################################################## + sub PrintProcessors + { + my $processor; + Debug("Current processing chain:", 3); + my $i = 0; + foreach $processor (@Processors) { + Debug($processor." type ".$ProcessorTypes{$Processors[$i]}, 3); + $i++; + } + } + + ############################################################################## + # AddProcessor(function[, first[, type]]) + # add a line processor to processing chain, defaults to end of chain + # if "first" is set to one adds processor to start of chain + ############################################################################## + sub AddProcessor + { + my $function = shift; + my $first = 0; + my $type = 0; + # check if flag to add processor to start of chain is set + if($#_ > -1) { $first = shift; } + # check if processor has a type + if($#_ > -1) { $type = shift; } + # adding processor to start of chasin + if($first) { + @Processors = reverse(@Processors); + } + push(@Processors, $function); + if($first) { + @Processors = reverse(@Processors); + } + $ProcessorTypes{$function} = $type; + Debug("Added processor ".$function." of type ".$type, 2); + if($debug > 1) { PrintProcessors(); } + } + + ############################################################################## + # AddProcessorAfter(function, processor[, type]) + # add a line processor to processing chain immediately after an existing + # processor, if existing processor not found, new processor is added to + # end of chain + ############################################################################## + sub AddProcessorAfter + { + my $function = shift; + my $existing = shift; + my $type = 0; + # check if processor has a type + if($#_ > -1) { $type = shift; } + my $i = 0; + my $found = 0; + my @CurrentProcessors = @Processors; + my $processor; + # reset processing chain + @Processors = (); + foreach $processor (@CurrentProcessors) { + push(@Processors, $processor); + if(!$found) { + # check done as regular expression for greater flexibility + if($processor =~ /$existing/) { + push(@Processors, $function); + $found = 1; + } + } + } + if(!$found) { + Warning("Did not find processor $existing in chain, processor $processor added to end of list"); + AddProcessor($function, 0, $type); + return; + } + $ProcessorTypes{$function} = $type; + Debug("Added processor ".$function." of type ".$type, 2); + if($debug > 1) { PrintProcessors(); } + } + + ############################################################################## + # AddProcessorBefore(function, processor[, type]) + # add a line processor to processing chain immediately after an existing + # processor, if existing processor not found, new processor is added to + # end of chain + ############################################################################## + sub AddProcessorBefore + { + my $function = shift; + my $existing = shift; + my $type = 0; + # check if processor has a type + if($#_ > -1) { $type = shift; } + my $i = 0; + my $found = 0; + my @CurrentProcessors = @Processors; + my $processor; + # reset processing chain + @Processors = (); + foreach $processor (@CurrentProcessors) { + if(!$found) { + # check done as regular expression for greater flexibility + if($processor =~ /$existing/) { + push(@Processors,$function); + $found = 1; + } + } + push(@Processors, $processor); + } + if(!$found) { + Warning("Did not find processor $existing in chain, processor $processor added to start of list"); + AddProcessor($function, 1, $type); + return; + } + $ProcessorTypes{$function} = $type; + Debug("Added processor ".$function." of type ".$type, 2); + if($debug > 1) { PrintProcessors(); } + } + + ############################################################################## + # RemoveProcessor(function) + # remove a processor name "function" from list + ############################################################################## + sub RemoveProcessor + { + my $function = shift; + my $i = 0; + # find function + while($i <= $#Processors && $Processors[$i] ne $function) { $i++; } + # check function found + if($i > $#Processors) { + Warning("Attempt to remove function ".$function. + " which does not exist"); + return; + } + # remove function + for(; $i<$#Processors; $i++) { + $Processors[$i] = $Processors[$i+1]; + } + pop(@Processors); + delete($ProcessorTypes{$function}); + Debug("Removed processor ".$function, 2); + PrintProcessors(); + } + + + ############################################################################## + # Add a function to run each time a base file is opened + ############################################################################## + sub AddOpenInputFunc + { + my $func = shift; + push(@OpenInputFuncs, $func); + } + + ############################################################################## + # Add a function to run each time a base file is closed + ############################################################################## + sub AddCloseInputFunc + { + my $func = shift; + push(@CloseInputFuncs, $func); + } + + ############################################################################## + # Add a function to run each time a base file is opened + ############################################################################## + sub AddOpenOutputFunc + { + my $func = shift; + push(@OpenOutputFuncs, $func); + } + + ############################################################################## + # Add a function to run each time a base file is closed + ############################################################################## + sub AddCloseOutputFunc + { + my $func = shift; + push(@CloseOutputFuncs, $func); + } + + + ############################################################################## + # AddKeyword(keyword, function) + # Define a new keyword, when keyword (preceded by keyword char) is found, + # function is run on the remainder of the line. + ############################################################################## + sub AddKeyword + { + my $keyword = shift; + my $function = shift; + $Keywords{$keyword} = $function; + Debug("Added keyword ".$keyword." which runs ".$function, 2); + } + + + ############################################################################## + # RemoveKeyword(keyword) + # Keyword is deleted from list, all occurrences of keyword found in + # document are ignored. + ############################################################################## + sub RemoveKeyword + { + my $keyword = shift; + delete $Keywords{$keyword}; + # sort keywords index into reverse order, this ensures #if[n]def comes + # before #if when comparing input with keywords + Debug("Removed keyword ".$keyword, 2); + } + + + ############################################################################## + # RemoveAllKeywords - removes all current keywords. + ############################################################################## + sub RemoveAllKeywords + { + %Keywords = (); + Debug("Removed all current keywords", 2); + } + + + ############################################################################## + # AddIfword - adds a keyword to ifword hash + ############################################################################## + sub AddIfword + { + my $ifword = shift; + $Ifwords{$ifword} = ''; + Debug("Added Ifword: ".$ifword, 2); + } + + ############################################################################## + # RemoveIfword - removes a keyword from ifword hash + ############################################################################## + sub RemoveIfword + { + my $ifword = shift; + delete $Ifwords{$ifword}; + Debug("Removed Ifword: ".$ifword, 2); + } + + ############################################################################## + # AddElseword - adds a keyword to elseword hash + ############################################################################## + sub AddElseword + { + my $elseword = shift; + $Elsewords{$elseword} = ''; + Debug("Added Elseword: ".$elseword, 2); + } + + ############################################################################## + # RemoveElseword - removes a keyword from elseword hash + ############################################################################## + sub RemoveElseword + { + my $elseword = shift; + delete $Elsewords{$elseword}; + Debug("Removed Elseword: ".$elseword, 2); + } + + ############################################################################## + # AddEndifword - adds a keyword to endifword hash + ############################################################################## + sub AddEndifword + { + my $endifword = shift; + $Endifwords{$endifword} = ''; + Debug("Added Endifword: ".$endifword, 2); + } + + ############################################################################## + # RemoveEndifword - removes a keyword from endifword hash + ############################################################################## + sub RemoveEndifword + { + my $endifword = shift; + delete $Endifwords{$endifword}; + Debug("Removed Endifword: ".$endifword, 2); + } + + + ############################################################################## + # AddIncludePath - adds another include path to the list + ############################################################################## + sub AddIncludePath + { + my $path = shift; + push(@IncludePaths, $path); + Debug("Added include path: \"".$path."\"", 2); + } + + + ############################################################################## + # AddModulePath - adds another module search path to the list + ############################################################################## + sub AddModulePath + { + my $path = shift; + push(@INC, $path); + Debug("Added module path: \"".$path."\"", 2); + } + + + # set if file being written to has same name as input file + my $same_file = ""; + + ############################################################################## + # OpenOutputFile - opens the output file + ############################################################################## + sub OpenOutputFile + { + $outputfile = shift; + Debug("Output file: ".$outputfile, 1); + + # check for outputfile name, if not specified use STDOUT + if($outputfile eq "") { $outputfile = "-"; } + + # output is not stdout and file with that name already exists + if($outputfile ne "-" && FileExists($outputfile) ) { + $same_file = $outputfile; + # paranoid: check file is writable and normal file + if(-w $outputfile && -f $outputfile) { + $outputfile = $outputfile.".fpp".$$; + my $i=0; # paranoid: check temp file does not exist + while(FileExists($outputfile)) { + $outputfile = $outputfile.$i; + $i++; + if($i >= 10) { Error("Cound not get temp filename"); } + } + } + else { + Error("Cannot read or write to ".$outputfile); + } + } + if(!open(OUTPUT, ">".$outputfile)) { + Error("Cannot open output file: ".$outputfile); + } + # run any open functions + my $func; + foreach $func (@OpenOutputFuncs) { $func->(); } + } + + + ############################################################################## + # CloseOutputFile - close the output file + ############################################################################## + sub CloseOutputFile + { + # run any close functions + my $func; + foreach $func (@CloseOutputFuncs) { $func->(); } + close(OUTPUT); + + # if input and output have same name, rename output to input now + if($same_file ne "") { + if(rename($same_file, $same_file."~") == -1) { + Error("Could not rename ".$same_file." ".$same_file."~"); + } + if(rename($outputfile, $same_file) == -1) { + Error("Could not rename ".$outputfile." ".$same_file); + } + } + # reset same_file + $same_file = ""; + } + + + ############################################################################## + # ChangeOutputFile - change the output file + ############################################################################## + sub ChangeOutputFile + { + CloseOutputFile(); + $outputfile = shift; + OpenOutputFile($outputfile); + } + + + ############################################################################## + # AddInputFile - adds another input file to the list + ############################################################################## + sub AddInputFile + { + my $file = shift; + push(@Inputfiles, $file); + Debug("Added input file: \"".$file."\"", 2); + } + + + ############################################################################## + # UseModule(module) + # Module "module.pm" is used, "module.pm" can be any perl module and can use + # or replace any of the functions in this package + ############################################################################## + sub UseModule + { + my $module = shift; + Debug("Loading module ".$module, 1); + require $module; + if($@) { Error($@); } + } + + + ############################################################################## + # find end of next word in $sline, assumes leading whitespace removed + ############################################################################## + sub GetNextWordEnd + { + my $sline = shift; + # check for whitespace in this string + if($sline =~ /\s/) { + # return length of everything up to first whitespace + return length($`); + } + # whitespace not found, return length of the whole string + return length($sline); + } + + + ############################################################################## + # Print current table of defines - used for debugging + ############################################################################## + sub PrintDefines + { + my $define; + Debug("Current ".$keywordchar."define's:", 3); + foreach $define (keys(%Defines)) { + Debug(" macro:\"".$define."\", definition:\"".$Defines{$define}."\"",3); + } + } + + + ############################################################################## + # DefineEnv - define's all environment variables to macros, each prefixed + # by $envchar + ############################################################################## + sub DefineEnv + { + my $macro; + Debug("Defining environment variables as macros", 2); + foreach $macro (keys(%ENV)) { + Define($envchar.$macro." ".$ENV{$macro}); + } + } + + + ############################################################################## + # Find out if arguments have been used with macro + ############################################################################## + sub DefineArgsUsed + { + my $string = shift; + # check '(' is first non-whitespace char after macro + if($string =~ /^\s*\(/) { + return 1; + } + return 0; + } + + + ############################################################################## + # ParseArgs($string) - find the arguments in a string of form + # (arg1, arg2, arg3...) trailing chars + # or + # arg1, arg2, arg3... + ############################################################################## + sub ParseArgs + { + my $string = shift; + $string = CleanStart($string); + my @Chars; + my $char; + # split string into chars (can't use split coz it deletes \n at end) + for($char=0; $char ')', '"' => '"', '\'' => '\''); + my $s = -1; # start of chars + my $backslash = 0; + # number of special char pairs to allow + my $pairs = 1; + + # deal with first '(' if there (ie func(args) rather than func args) + if($#Chars >= 0 && $Chars[0] eq '(') { + push(@Endchar, ')'); + $Chars[0] = ''; + $s++; + $pairs++; # ignore this pair of special char pairs + } + + # replace args with their values + foreach $char (@Chars) { + # deal with end of special chars, ),",' etc. + if($#Endchar > -1 && $char eq $Endchar[$#Endchar]) { + # if char before this was a backslash, ignore this char + if($backslash) { + chop($arg); # delete backslash from string + } + else { + # pop end char of list and reduce pairs if its a bracket + if(pop(@Endchar) eq ')') { $pairs--; } + } + } + # deal with start of special chars + elsif(exists($SpecialChars{$char})) { + # if char before this was a backslash, ignore this char + if($backslash) { + chop($arg); # delete backslash from string + } + # only start new pair if not already in special char pair + # (not including main args brackets of course) + elsif($#Endchar < $pairs-1) { + push(@Endchar, $SpecialChars{$char}); + # need to treat brackets differently for macros within + # macros "this(that(tother)))", otherwise lose track of ()'s + if($char eq '(') { $pairs++; } + } + } + # deal with ',', add arg to list and start search for next one + elsif($#Endchar == $s && $char eq ',') { + # if char before this was a backslash, ignore this char + if($backslash) { + chop($arg); # delete backslash from string + } + else { + push(@Args, CleanStart($arg)); + $char = ''; + $arg = ""; + next; + } + } + # deal \\ with an escaping \ ie. \" or \, or \\ + if($char eq '\\') { + if($backslash) { # found \\ + $backslash = 0; # second backslash ignored + chop($arg); # delete backslash from string + } + else{$backslash = 1;} + } + elsif($backslash) { $backslash = 0; } + # check for end of args string + if($#Endchar < $s) { + push(@Args, CleanStart($arg)); + $char = ''; + # put remainder of string back together + $arg = join('', @Chars); + last; + } + $arg = $arg.$char; # add char to current arg + $char = ''; # set char to null + } + + # deal with last arg or string following args if it exists + push(@Args, $arg); + + return @Args; + } + + + ############################################################################## + # Find the arguments in a macro and replace them + ############################################################################## + sub FindDefineArgs + { + my $substring = shift; + my $macro = shift; + + # get definition list for this macro + my @Argnames = split(/\,/, $DefinesArgs{$macro}); + + # check to see if macro can have any number of arguments (last arg ...) + my $anyargs = ($#Argnames >= 0 && $Argnames[$#Argnames] =~ /\.\.\.\Z/o); + + # get arguments passed to this macro + my @Argvals = ParseArgs($substring); + # everything following macro args should be returned as tail + my $tail = pop(@Argvals); + + # check the right number of args have been passed, should be all args + # present plus string at end of args (assuming macro cannot have any number + # of arguments) + if(!$anyargs && $#Argvals != $#Argnames) { + # show warning if wrong args (unless macro should have zero args and + # 1 arg provided which is blank space + if(!($#Argnames == -1 && $#Argvals == 0 && $Argvals[0] =~ /\A\s*\Z/)) { + Warning("Macro \'".$macro."\' used with ".$#Argvals. + " args, expected ".($#Argnames+1)); + } + # delete all excess args + while($#Argvals > $#Argnames) { pop(@Argvals); } + } + # make all missing args blanks + while($#Argvals < $#Argnames) { push(@Argvals, ""); } + + return (@Argvals, $tail); + } + + + ############################################################################## + # FunctionMacro: used with functions to inform a module which macro + # was being replaced when the function was called - used in bigfunc.pm + ############################################################################## + my $functionmacro = ""; + sub FunctionMacro + { + return $functionmacro; + } + + + ############################################################################## + # Replace all defined macro's arguments with their values + # Inputs: + # $macro = the macro to be replaces + # $string = the string following the occurrence of macro + ############################################################################## + sub ReplaceDefineArgs + { + my ($string, $tail, %Used) = @_; + # check if args used, if not do nothing + if(DefineArgsUsed($tail)) { + my $macro = $string; + # get arguments following macro + my @Argvals = FindDefineArgs($tail, $macro); + $tail = pop(@Argvals); # tail returned as last element + + my @Argnames = split(/\,/, $DefinesArgs{$macro}); + my ($i, $j); + + # replace previous macro with defn + args + $string = $Defines{$macro}; + + # check if macro should call a function + if(exists($DefinesFuncs{$macro})) { + # replace all macros in argument list + for($i=0; $i<=$#Argvals; $i++) { + $Argvals[$i] = ReplaceDefines($Argvals[$i]); + } + if($debug > 1) { + my $argstring = ""; + if($#Argvals >= 0) { $argstring = join(", ", @Argvals); } + Debug("Running function $DefinesFuncs{$macro} with args (". + $argstring.")", 2); + } + # set name of macro which is being parse (needed in bigfunc.pm) + $functionmacro = $macro; + $string = $DefinesFuncs{$macro}->(@Argvals); + # don't need do anything else, return now + return $string, $tail; + } + + # check if last arg ends in ... (allows any number of args in macro) + if($#Argnames >= 0 && $Argnames[$#Argnames] =~ s/\.\.\.\Z//o) { + # concatanate all extra args into final arg + while($#Argvals > $#Argnames) { + my $arg1 = pop(@Argvals); + my $arg2 = pop(@Argvals); + push(@Argvals, $arg2.", ".$arg1); + } + # check for ## at start of macro name in args list + if($string =~ /\#\#$Argnames[$#Argnames]/) { + # if last argument is empty remove preciding "," + if($#Argvals == $#Argnames && $Argvals[$#Argnames] eq "") { + $string =~ s/\,\s*\#\#$Argnames[$#Argnames]//g; + } + else { + $string =~ + s/\#\#$Argnames[$#Argnames]/$Argnames[$#Argnames]/g; + } + } + } + + # to get args passed to macro to same processed level as rest of + # macro, they need to be checked for occurrences of all used macros, + # this is a nasty hack to temporarily change defines list to %Used + { + my %RealDefines = %Defines; + my $realdefmin = $defmin; + my $realdefmax = $defmax; + my %RealDefineLookup = %DefineLookup; + %Defines = %Used; + GenerateDefinesKeys(); + + for($i=0; $i<=$#Argvals; $i++) { + $Argvals[$i] = ReplaceDefines($Argvals[$i]); + } + + # return defines to normal + %Defines = %RealDefines; + $defmin = $realdefmin; + $defmax = $realdefmax; + %DefineLookup = %RealDefineLookup; + } + + # The next step replaces argnames with argvals. Once a bit of string + # has been replaced it is removed from further processing to avoid + # unwanted recursive macro replacement. + my @InString = ( $string ); # string to be replaced + my @InDone = ( 0 ); # flag to say if string section replaced + my @OutString; # output of string sections after each + # macro has been replaced + my @OutDone; # output flags + my $k = 0; + for($i=0; $i<=$#Argnames; $i++) { + for($j=0; $j<=$#InString; $j++) { + if($InDone[$j] == 0) { + # replace macros and split up string so replaced part + # is flagged as done and rest is left for further + # processing + while($InString[$j] =~ /$bound$Argnames[$i]$bound/) { + $OutString[$k] = $`; $OutDone[$k] = 0; + $k++; + $OutString[$k] = $Argvals[$i]; $OutDone[$k] = 1; + $k++; + $InString[$j] = $'; # one more quote for emacs ' + } + } + $OutString[$k] = $InString[$j]; $OutDone[$k] = $InDone[$j]; + $k++; + } + @InString = @OutString; @InDone = @OutDone; + $k = 0; + } + # rebuild string + $string = join('', @InString); + + Debug("Replaced \"".$macro."\" for \"".$string."\" [".$recurse_level."]", 2); + } + else { + Debug("Macro \"".$string."\" found without args, ignored", 2); + } + return ($string, $tail); + } + + + ############################################################################## + # When replacing macros with args, the macro and everything following the + # macro (the tail) are passed to ReplaceDefineArgs. The function extracts + # the args from the tail and then returns the replaced macro and the new + # tail. This function extracts the remaining part of the real tail from + # the current input string. + ############################################################################## + sub ReclaimTail + { + my ($input, $tail) = @_; + # split strings into chars and compare each one until difference found + my @Input = split(//, $input); + my @Tail = split(//, $tail); + $tail = $input = ""; + while($#Input >= 0 && $#Tail >= 0 && $Input[$#Input] eq $Tail[$#Tail]) { + $tail = pop(@Tail).$tail; + pop(@Input); + } + while($#Input >=0) { $input = pop(@Input).$input; } + return ($input, $tail); + } + + + ############################################################################## + # Replace all defined macro's in a line with their value. Recursively run + # through macros as many times as needed (to find macros within macros). + # Inputs: + # $input = string to process + # $tail = rest of line following $string (if any), this will only be used + # if string contains a macro with args, the args will probably be + # at the start of the tail + # %Used = all macros found in $string so far, these will not be checked + # again to avoid possible recursion + # Initially just $input is passed in, other args are added for recursive calls + ############################################################################## + sub ReplaceDefines + { + my ($input, $tail, %Used) = @_; + # check for recursive macro madness (set to same level as Perl warning) + if(++$recurse_level > 97) { + $recurse_level--; + Warning("Recursive macro detected in \"".$input."\""); + if($tail) { return ($input, $tail); } + return $input; + } + + my $out = ""; # initialise output to empty string + OUTER : while($input =~ /\S/o) { + my ($macro, $string); + my @Words; + + + ###################################################################### + # if macros start with prefix, skip to next prefix + ###################################################################### + if($macroprefix ne "") { + my $found = 0; + # find next potential macro in line if any + while(!$found && $input =~ /$macroprefix\S/) { + # everything before prefix + $out = $out.$`; + # reclaim first char in macro + my $match = $&; + # everything after prefix + $input = chop($match).$'; # one more quote for emacs ' + # check if first chars are in macro + if(exists($DefineLookup{substr($input, 0, $defmin)})) { + $found = 1; + } + # put prefix back onto output and carry on searching + else { $out = $out.$match; } + } + # no more macros + if(!$found) { $out = $out.$input; $input = ""; last OUTER; } + } + + + ###################################################################### + # replacing macros which are "words" only - quick and easy + ###################################################################### + if($bound eq '\b') { + @Words = split(/(\w+)/, $input, 2); + $out = $out.$Words[0]; + if($#Words == 2) { $macro = $Words[1]; $input = $Words[2]; } + else { $input = ""; last OUTER; } + } + + ###################################################################### + # replacing all types of macro - slow and horrid + ###################################################################### + else { + # forward string to next non-whitespace char that starts a macro + while(!exists($DefineLookup{substr($input, 0, $defmin)})) { + if($input =~ /^\s/ ) { # remove preceding whitespace + @Words = split(/^(\s+)/, $input, 2); + $out = $out.$Words[1]; + $input = $Words[2]; + } + else { # skip to next char + $out = $out.substr($input, 0, 1); + $input = substr($input, 1); + } + if($input eq "") { last OUTER; } + } + # remove the longest possible potential macro (containing no + # whitespace) from the start of input + @Words = split(/(\s+)/, $input, 2); + $macro = $Words[0]; + if($#Words == 2) {$input = $Words[1].$Words[2]; } + else {$input = ""; } + # shorten macro if too long + if(length($macro) > $defmax) { + $input = substr($macro, $defmax).$input; + $macro = substr($macro, 0, $defmax); + } + # see if a macro exists in "macro" + while(length($macro) > $defmin && + !(exists($Defines{$macro}) && !exists($Used{$macro}))) { + # chop a char off macro and try again + $input = chop($macro).$input; + } + } + + # check if macro is at start of string and has not been used yet + if(exists($Defines{$macro}) && !exists($Used{$macro})) { + # set macro as used + $Used{$macro} = $Defines{$macro}; + # temporarily add tail to input + if($tail) { $input = $input.$tail; } + # replace macro with defn + if(CheckDefineArgs($macro)) { + ($string, $input) = ReplaceDefineArgs($macro, $input, %Used); + } + else { + $string = $Defines{$macro}; + Debug("Replaced \"".$macro."\" for \"".$string."\" [".$recurse_level."]", 2); + } + + ($string=~ m/\#\#/) and ($string=~ s/\s*\#\#\s*//gm); + + @Words = ReplaceDefines($string, $input, %Used); + $out = $out.$Words[0]; + if($#Words == 0) { $input = ""; } + else { + # remove space up to start of next char + if(CheckEatTrail($macro)) { $Words[1] =~ s/^[ \t]*//o; } + $input = $Words[1]; + } + delete($Used{$macro}); + # reclaim all unparsed tail + if($tail && $tail ne "") { + ($input, $tail) = ReclaimTail($input, $tail); + } + } + # macro not matched, add to output and move swiftly on + else { + if($bound eq '\b') { $out = $out.$macro; } + else { + $out = $out.substr($macro, 0, 1); + $input = substr($macro, 1).$input; + } + } + } + $recurse_level--; + # append any whitespace left in string and return it + if($tail) { return ($out.$input, $tail); } + return $out.$input; + } + + + ############################################################################## + # GenerateDefinesKey creates all keys and indices needed for %Defines + ############################################################################## + sub GenerateDefinesKeys + { + # find longest and shortest macro + my ($define, $length) = each %Defines; + $defmin = $defmax = length($define); + %DefineLookup = (); + foreach $define (keys(%Defines)) { + $length = length($define); + if($length > $defmax) { $defmax = $length; } + if($length < $defmin) { $defmin = $length; } + } + # regenerate lookup table of first letters + foreach $define (keys(%Defines)) { + $DefineLookup{substr($define, 0, $defmin)} = 1; + } + } + + + ############################################################################## + # Set a define + ############################################################################## + sub SetDefine + { + my ($macro, $value) = @_; + # add macro and value to hash table + $Defines{$macro} = $value; + # add define to keys + my $length = length($macro); + if($length < $defmin || $defmin == 0) { GenerateDefinesKeys(); } + else { + if($length > $defmax) { $defmax = $length; } + $length = substr($macro, 0, $defmin); + $DefineLookup{$length} = 1; + } + } + + + ############################################################################## + # Get a define without doing any macro replacement + ############################################################################## + sub GetDefine + { + my $macro = shift; + return $Defines{$macro}; + } + + + ############################################################################## + # Replace a define, checks if macro defined and only redefine's if it is + ############################################################################## + sub Redefine + { + my $macro = shift; + my $value = shift; + # check if defined + if(CheckDefine($macro)) { SetDefine($macro, $value); } + } + + + ############################################################################## + # Set a define argument list + ############################################################################## + sub SetDefineArgs + { + my $macro = shift; + my $args = shift; + # add macro args to hash table + $DefinesArgs{$macro} = $args; + } + + + ############################################################################## + # Set a function which should be called when a macro is found + ############################################################################## + sub SetDefineFuncs + { + my $macro = shift; + my $func = shift; + # add macro function to hash table + $DefinesFuncs{$macro} = $func; + } + + + ############################################################################## + # Check if a macro is defined + ############################################################################## + sub CheckDefine + { + my $macro = shift; + return exists($Defines{$macro}); + } + + + ############################################################################## + # Check if a macro is defined and has arguments + ############################################################################## + sub CheckDefineArgs + { + my $macro = shift; + return exists($DefinesArgs{$macro}); + } + + + ############################################################################## + # Check if a macro is defined and calls a function + ############################################################################## + sub CheckDefineFuncs + { + my $macro = shift; + return exists($DefinesFuncs{$macro}); + } + + + ############################################################################## + # Check if a macro is defined and eats trailing whitespace + ############################################################################## + sub CheckEatTrail + { + my $macro = shift; + return exists($EatTrail{$macro}); + } + + + ############################################################################## + # Set eat-trailing-whitespace for a macro + ############################################################################## + sub SetEatTrail + { + my $macro = shift; + $EatTrail{$macro} = 1; + } + + + ############################################################################## + # Test if a file exists and is readable + ############################################################################## + sub FileExists + { + my $filename = shift; + # test if file is readable and not a directory + if( !(-r $filename) || -d $filename ) { + Debug("Checking for file: ".$filename."...not found!", 2); + return 0; + } + Debug("Checking for file: ".$filename."...found!", 2); + return 1; + } + + + ############################################################################## + # #comment - rest of line ignored as a comment + ############################################################################## + sub Comment + { + # nothing to be done here + Debug("Commented line", 2); + } + + + ############################################################################## + # Define a variable, accepted inputs: + # $macrodefn = $macro $defn - $macro associated with $defn + # ie: #define TEST test string + # $macro = TEST, $defn = "test string" + # Note: $defn = rest of line after $macro + # $macrodefn = $macro - $macro defined without a defn, rest of line ignored + # ie: #define TEST_DEFINE + # $macro = TEST_DEFINE, $defn = "1" + ############################################################################## + sub Define + { + my $macrodefn = shift; + my $macro; + my $defn; + my $i; + + # check there is an argument + if($macrodefn !~ /\S/o) { + Filepp::Error("define keyword used without arguments"); + } + + # find end of macroword - assume separated by space or tab + $i = GetNextWordEnd($macrodefn); + + # separate macro and defn (can't use split, doesn't work with '0') + $macro = substr($macrodefn, 0, $i); + $defn = substr($macrodefn, $i); + + # strip leading whitespace from $defn + if($defn) { + $defn =~ s/^[ \t]*//; + } + else { + $defn = ""; + } + + # check if macro has arguments (will be a '(' in macro) + if($macro =~ /\(/) { + # split up macro, args and defn - delimiters = space, (, ), ',' + my @arglist = split(/([\s,\(,\),\,])/, $macro." ".$defn); + my $macroargs = ""; + my $arg; + + # macro is first element in list, remove it from list + $macro = $arglist[0]; + $arglist[0] = ""; + # loop through list until ')' and find all args + foreach $arg (@arglist) { + if($arg) { + # end of arg list, leave loop + if($arg eq ")") { + $arg = ""; + last; + } + # ignore space, ',' and '(' + elsif($arg =~ /([\s,\,,\(])/) { + $arg = ""; + } + # argument found, add to ',' separated list + else { + $macroargs = $macroargs.",".$arg; + $arg = ""; + } + } + } + $macroargs = Strip($macroargs, ",", 1); + # store args + SetDefineArgs($macro, $macroargs); + + Debug("Define: macro ".$macro." has args (".$macroargs.")", 2); + # put rest of defn back together + $defn = join('', at arglist); + $defn = CleanStart($defn); + } + # make sure macro is not being redefined and used to have args + else { + delete($DefinesArgs{$macro}); + delete($DefinesFuncs{$macro}); + } + + # define the macro defn pair + SetDefine($macro, $defn); + + Debug("Defined \"".$macro."\" to be \"".$defn."\"", 2); + if($debug > 2) { PrintDefines(); } + } + + + + ############################################################################## + # Else, standard if[n][def]-else-endif + # usage: #else somewhere between #if[n][def] key and #endif + ############################################################################## + sub Else + { + # else always true - only ran when all preceding 'if's have failed + return 1; + } + + + ############################################################################## + # Endif, standard ifdef-[else]-endif + # usage: #endif somewhere after #ifdef key and optionally #else + ############################################################################## + sub Endif + { + # this always terminates an if block + return 1; + } + + + ############################################################################## + # If conditionally includes or ignores parts of a file based on expr + # usage: #if expr + # expr is evaluated to true(1) or false(0) and include usual ==, !=, > etc. + # style comparisons. The "defined" keyword can also be used, ie: + # #if defined MACRO || !defined(MACRO) + ############################################################################## + sub If + { + my $expr = shift; + Debug("If: parsing: \"".$expr."\"", 2); + + # check for any "defined MACRO" tests and evaluate them + if($expr =~ /defined/) { + my $indefined = 0; + + # split expr up into its component parts, the split is done on the + # following list of chars and strings: '!','(',')','&&','||', space + my @Exprs = split(/([\s,\!,\(,\)]|\&\&|\|\|)/, $expr); + + # search through parts for "defined" keyword and check if macros + # are defined + foreach $expr (@Exprs) { + if($indefined == 1) { + # previously found a defined keyword, check if next word + # could be the macro to test for (not any of the listed chars) + if($expr && $expr !~ /([\s,\!,\(,\)]|\&\&|\|\|)/) { + # replace macro with 0 or 1 depending if it is defined + Debug("If: testing if \"".$expr."\" defined...", 2); + if(CheckDefine($expr)) { + $expr = 1; + Debug("If: defined", 2); + } + else { + $expr = 0; + Debug("If: NOT defined", 2); + } + $indefined = 0; + } + } + elsif($expr eq "defined") { + # get rid of defined keyword + $expr = ""; + # search for next macro following "defined" + $indefined = 1; + } + } + + # put full expr string back together + my $newexpr = join('', at Exprs); + $expr = $newexpr; + } + + # pass parsed line though processors + $expr = RunProcessors($expr); + + # evaluate line and return result (1 = true) + Debug("If: evaluating \"".$expr."\"", 2); + my $result = eval($expr); + # check if statement is valid + if(!defined($result)) { Warning($@); } + elsif($result) { + Debug("If: \"".$expr."\" true", 1); + return 1; + } + Debug("If: \"".$expr."\" false", 1); + return 0; + } + + + ############################################################################## + # Elif equivalent to "else if". Placed between #if[n][def] and #endif, + # equivalent to nesting #if's + ############################################################################## + sub Elif + { + my $input = shift; + return If($input); + } + + + ############################################################################## + # Ifdef conditionally includes or ignores parts of a file based on macro, + # usage: #ifdef MACRO + # if macro has been previously #define'd everything following the + # #ifdef will be included, else it will be ignored until #else or #endif + ############################################################################## + sub Ifdef + { + my $macro = shift; + + # separate macro from any trailing garbage + $macro = substr($macro, 0, GetNextWordEnd($macro)); + + # check if macro defined - if not set to be #ifdef'ed out + if(CheckDefine($macro)) { + Debug("Ifdef: ".$macro." defined", 1); + return 1; + } + Debug("Ifdef: ".$macro." not defined", 1); + return 0; + } + + + ############################################################################## + # Ifndef conditionally includes or ignores parts of a file based on macro, + # usage: #ifndef MACRO + # if macro has been previously #define'd everything following the + # #ifndef will be ignored, else it will be included until #else or #endif + ############################################################################## + sub Ifndef + { + my $macro = shift; + + # separate macro from any trailing garbage + $macro = substr($macro, 0, GetNextWordEnd($macro)); + + # check if macro defined - if not set to be #ifdef'ed out + if(CheckDefine($macro)) { + Debug("Ifndef: ".$macro." defined", 1); + return 0; + } + Debug("Ifndef: ".$macro." not defined", 1); + return 1; + } + + + ############################################################################## + # Parses all macros from file, but discards all other output + ############################################################################## + sub IncludeMacros + { + my $file = shift; + my $currentoutput = $output; + SetOutput(0); + Parse($file); + SetOutput($currentoutput); + } + + + ############################################################################## + # Include $filename in output file, format: + # #include "filename" - local include file, ie. in same directory, try -Ipath + # also if not not found in current directory + # #include - system include file, use -Ipath + ############################################################################## + sub Include + { + my $input = shift; + my $filename = $input; + my $fullname; + my $sysinclude = 0; + my $found = 0; + my $i; + + # check for recursive includes (level set to same as Perl recurse warn) + if($include_level >= 98) { + Warning("Include recursion too deep - skipping \"".$filename."\"\n"); + return; + } + + # replace any defined values in the include line + $filename = RunProcessors($filename); + + # check if it is a system include file (#include ) or a local + # include file (#include "filename") + if(substr($filename, 0, 1) eq "<") { + $sysinclude = 1; + # remove <> from filename + $filename = substr($filename, 1); + ($filename) = split(/\>/, $filename, 2); + } + elsif(substr($filename, 0, 1) eq "\"") { + # remove double quotes from filename + $filename = substr($filename, 1); + ($filename) = split(/\"/, $filename, 2); + } + # else assume filename given without "" or <>, naughty but allowed + + # check for file in current directory + if($sysinclude == 0) { + # get name of directory base file is in + my $dir = ""; + if($file =~ /\//) { + my @Dirs = split(/(\/)/, $file); + for($i=0; $i<$#Dirs; $i++) { + $dir = $dir.$Dirs[$i]; + } + } + if(FileExists($dir.$filename)) { + $fullname = $dir.$filename; + $found = 1; + } + } + + # search for file in include paths, first path on command line first + $i = 0; + while($found == 0 && $i <= $#IncludePaths) { + $fullname = $IncludePaths[$i]."/".$filename; + if(FileExists($fullname)) { $found = 1; } + $i++; + } + + # include file if found, error if not + if($found == 1) { + Debug("Including file: \"".$fullname."\"", 1); + # recursively call Parse + Parse($fullname); + } + else { + Warning("Include file \"".$filename."\" not found", 1); + } + } + + + + ############################################################################## + # Pragma filepp Function Args + # Pragma executes a filepp function, everything following the function name + # is passed as arguments to the function. + # The format is: + # #pragma filepp function args... + # If pragma is not followed by "filepp", it is ignored. + ############################################################################## + sub Pragma + { + my $input = shift; + + # check for "filepp" in string + if($input =~ /^filepp\b/) { + my ($function, $args); + ($input, $function, $args) = split(/\s/, $input, 3); + if($function) { + if(!$args) { $args = ""; } + if($safe_mode) { + Debug("Safe mode enabled, NOT running: ".$function."(".$args.")", 1); + } + else { + my @Args = ParseArgs($args); + Debug("Running function: ".$function."(".$args.")", 1); + $function->(@Args); + } + } + } + } + + + ############################################################################## + # Turn normal output on/off (does not affect any output produced by keywords) + # 1 = on, 0 = off + ############################################################################## + sub SetOutput + { + $output = shift; + Debug("Output set to ".$output, 2); + } + + + ############################################################################## + # Turn blank suppression on and off at this include level + # 1 = on, 0 = off + ############################################################################## + sub SetBlankSupp + { + $blanksupp[$include_level] = shift; + Debug("Blank suppression set to ".$blanksupp[$include_level], 2); + } + + + ############################################################################## + # Reset blank suppression to command-line value (except at level 0) + ############################################################################## + sub ResetBlankSupp + { + if($include_level == 0) { + $blanksupp[$include_level] = 0; + } else { + $blanksupp[$include_level] = $blanksuppopt; + } + Debug("Blank suppression reset to ".$blanksupp[$include_level], 2); + } + + + ############################################################################## + # Set if macros are only replaced if the macro is a 'word' + ############################################################################## + sub SetWordBoundaries + { + my $on = shift; + if($on) { + $bound = '\b'; + Debug("Word Boundaries turned on", 2); + } + else { + $bound = ''; + Debug("Word Boundaries turned off", 2); + } + } + + ############################################################################## + # DEPRECATED - this function will be removed in later versions, use Set + # Toggle if macros are only replaced if the macro is a 'word' + ############################################################################## + sub ToggleWordBoundaries + { + if($bound eq '\b') { SetWordBoundaries(1); } + else { SetWordBoundaries(0); } + } + + + ############################################################################## + # Set treating keywordchar, contchar, macroprefix and optlineendchar as + # Perl regexps + ############################################################################## + sub SetCharPerlre + { + $charperlre = shift; + Debug("Characters treated as Perl regexp's : ".$charperlre, 2); + } + + + ############################################################################## + # Undef a previously defined variable, usage: + # #undef $macro + ############################################################################## + sub Undef + { + my $macro = shift; + my $i; + + # separate macro from any trailing garbage + $macro = substr($macro, 0, GetNextWordEnd($macro)); + + # delete macro from table + delete $Defines{$macro}; + delete $DefinesArgs{$macro}; + delete $DefinesFuncs{$macro}; + + # and remove its eat-trailing-whitespace flag + if(CheckEatTrail($macro)) { delete $EatTrail{$macro}; } + + # regenerate keys + GenerateDefinesKeys(); + + Debug("Undefined macro \"".$macro."\"", 2); + if($debug > 1) { PrintDefines(); } + } + + + ############################################################################## + # UndefAll - undefines ALL macros + ############################################################################## + sub UndefAll + { + %Defines = (); + %DefineLookup = (); + %EatTrail = (); + $defmin = $defmax = 0; + Debug("Undefined ALL macros", 2); + if($debug > 1) { PrintDefines(); } + } + + + ############################################################################## + # #warning msg - print warning message "msg" + ############################################################################## + sub Warning + { + my $msg = shift; + my $lastdebug = $debug; + $debug = 1; + Debug($msg, 1); + $debug = $lastdebug; + } + + + ############################################################################## + # ParseLineEnd - takes in line from input most recently read and checks + # if line should be continued (ie. next line in input read and appended + # to current line). + # Returns two values: + # $more - boolean, 1 = read another line from input to append to this one + # 0 = no line continuation + # $line - the line to be read. If any modification needs to be done to the + # line for line contination, it is done here. + # Example: if line is to be continued: set $more = 1, then + # remove line continuation character and newline from end of + # $line and replace with line continuation character. + ############################################################################## + sub ParseLineEnd + { + my $thisline = shift; + my $more = 0; + # check if end of line has a continuation char, if it has get next line + if($thisline =~ /$contchar$/) { + $more = 1; + # remove backslash and newline + $thisline =~ s/$contchar\n\Z//; + # append line continuation character + $thisline = $thisline.$contrepchar; + } + return ($more, $thisline); + } + + + ############################################################################## + # Set name of function to take check if line shoule be continued + ############################################################################## + sub SetParseLineEnd + { + my $func = shift; + $parselineend = $func; + } + + ############################################################################## + # Get name of function to take check if line shoule be continued + ############################################################################## + sub GetParseLineEnd + { + return $parselineend; + } + + + ############################################################################## + # GetNextLine - returns the next line of the current INPUT line, + # line continuation is taken care of here. + ############################################################################## + sub GetNextLine + { + my $thisline = ; + if($thisline) { + Redefine("__LINE__", ++$line); + my $more = 0; + ($more, $thisline) = $parselineend->($thisline); + while($more) { + Debug("Line continuation", 2); + my $nextline = ; + if(!$nextline) { return $thisline; } + # increment line count + Redefine("__LINE__", ++$line); + ($more, $thisline) = $parselineend->($thisline.$nextline); + # maintain same number of lines in input as output + if($preserveblank) { Filepp::Output("\n"); } + } + } + return $thisline; + } + + + ############################################################################## + # Write($string) - writes $string to OUTPUT file + ############################################################################## + sub Write + { + my $string = shift; + print(OUTPUT $string); + } + + + ############################################################################## + # Output($string) - conditionally writes $string to OUTPUT file + ############################################################################## + sub Output + { + my $string = shift; + if($output) { Write($string); } + } + + # counter for number of #if[n][def] loops currently in + my $iflevel = 0; + # flag to control when to write output + my @Writing = (1); # initialise default to 'writing' + # flag to show if current 'if' block has passed a 'true if' + my @Ifdone = (0); # initialise first to 'not passed true if' + + ############################################################################## + # Keyword parsing routine + ############################################################################## + sub ParseKeywords + { + # input is next line in file + my $inline = shift; + my $outline = ""; + + my $thisline = $inline; + my $keyword; + my $found = 0; + # remove whitespace from start of line + $thisline = CleanStart($thisline); + # check if first char on line is a # + if($thisline && $thisline =~ /^$keywordchar/) { + # remove "#" and any following whitespace + $thisline =~ s/^$keywordchar\s*//g; + # remove the optional end line char + if($optlineendchar ne "") { + $thisline =~ s/$optlineendchar\Z//g; + } + # check for keyword + if($thisline && $thisline =~ /^\w+\b/ && exists($Keywords{$&})) { + $keyword = $&; + $found = 1; + # remove newline from line + chomp($thisline); + # remove leading whitespace and keyword from line + my $inline = CleanStart(substr($thisline, length($keyword))); + + # check for 'if' style keyword + if(exists($Ifwords{$keyword})) { + # increment ifblock level and set ifdone to same + # value as previous block + $iflevel++; + $Ifdone[$iflevel] = 0; + $Writing[$iflevel] = $Writing[$iflevel - 1]; + if(!$Writing[$iflevel]) { $Ifdone[$iflevel] = 1; } + } + # check for out of place 'else' or 'endif' style keyword + elsif($iflevel <= 0 && (exists($Elsewords{$keyword}) || + exists($Endifwords{$keyword}) )) { + Warning($keywordchar.$keyword." found without preceding ". + $keywordchar."[else]ifword"); + } + + # decide if to run 'if' or 'else' keyword + if(exists($Ifwords{$keyword}) || exists($Elsewords{$keyword})){ + if(!($Ifdone[$iflevel])) { + # check return value of 'if' + if($Keywords{$keyword}->($inline)) { + $Ifdone[$iflevel] = 1; + $Writing[$iflevel] = 1; + } + else { $Writing[$iflevel] = 0; } + } + else { $Writing[$iflevel] = 0; } + } + # check for 'endif' style keyword + elsif(exists($Endifwords{$keyword})) { + # run endif keyword and decrement iflevel if true + if($Keywords{$keyword}->($inline)) { $iflevel--; } + } + # run all other keywords + elsif($Writing[$iflevel]) { $Keywords{$keyword}->($inline); } + + # write a blank line if preserving blank lines + # (assumes keywords have no output) + if($preserveblank) { $outline = $outline."\n"; } + + } # keyword if statement + } + # no keywords in line - write line to file if not #ifdef'ed out + if(!$found && $Writing[$iflevel]) { + $outline = $outline.$inline; + } + # keep same number of files in output and input + elsif(!$found && $preserveblank) { $outline = $outline."\n"; } + + return $outline; + } + + ############################################################################## + # Main parsing routine + ############################################################################## + sub Parse + { + # change file being parsed to this file, remember last filename so + # it can be returned at the end + my $lastparse = $file; + $file = shift; + + Debug("Parsing ".$file."...", 1); + Redefine("__FILE__", $file); + + # reset line count, remembering previous count for future reference + my $lastcount = $line; + $line = 0; + Redefine("__LINE__", $line); + + # increment include level + Redefine("__INCLUDE_LEVEL__", ++$include_level); + + # set blank line suppression: + # no suppression for top level files + if($include_level == 0) { + $blanksupp[$include_level] = 0; + } + # include level 1 - set suppression to command line given value + elsif($include_level == 1) { + # inherit root value if set + if($blanksupp[0]) { $blanksupp[$include_level] = 1; } + else {$blanksupp[$include_level] = $blanksuppopt; } + } + # all other include levels - keep suppression at existing value + else { + $blanksupp[$include_level] = $blanksupp[$include_level - 1]; + } + + # reset RunProcessors function for this file + $Running[$include_level] = 0; + $Currentproc[$include_level] = 0; + + # open file and set its handle to INPUT + local *INPUT; + if(!open(INPUT, $file)) { + Error("Could not open file ".$file); + } + + # if a base file, run any initialisation functions + if($include_level == 0) { + my $func; + foreach $func (@OpenInputFuncs) { $func->(); } + } + + # parse each line of file + $_ = GetNextLine(); + # if in "shebang" mode, throw away first line (the #!/blah bit) + if($shebang) { + # check for "#!...perl ...filepp..." + if($_ && $_ =~ /^\#\!.*perl.+filepp/) { + Debug("Skipping first line (shebang): ".$_, 1); + $_ = GetNextLine(); + } + } + + while($_) { + # unless blank lines are suppressed at this include level + unless($blanksupp[$include_level] && /^\s*$/) { + # run processing chain (defaults to ReplaceDefines) + $_ = RunProcessors($_, 1); + # write output to file or STDOUT + if($output) { Write($_); } + } + $_ = GetNextLine(); + } + + # run any close functions + if($include_level == 0) { + my $func; + foreach $func (@CloseInputFuncs) { $func->(); } + } + + # check all #if blocks have been closed at end of parsing + if($lastparse eq "" && $iflevel > 0) { Warning("Unterminated if block"); } + + # close file + close(INPUT); + Debug("Parsing ".$file." done. (".$line." lines processed)", 1); + + # reset $line + $line = $lastcount; + Redefine("__LINE__", $line); + + # reset $file + $file = $lastparse; + Redefine("__FILE__", $file); + if($file ne "") { + Debug("Parsing returned to ".$file." at line ".$line, 1); + } + + # decrement include level + Redefine("__INCLUDE_LEVEL__", --$include_level); + + } + + ############################################################################## + # Main routine + ############################################################################## + + # parse command line + my $i=0; + my $argc=0; + while($ARGV[$argc]) { $argc++; } + + while($ARGV[$i]) { + + # suppress blank lines in header files + if($ARGV[$i] eq "-b") { + $blanksuppopt = 1; + } + + # read from stdin instead of file + elsif($ARGV[$i] eq "-c") { + AddInputFile("-"); + } + + # Defines: -Dmacro[=defn] or -D macro[=defn] + elsif(substr($ARGV[$i], 0, 2) eq "-D") { + my $macrodefn; + # -D macro[=defn] format + if(length($ARGV[$i]) == 2) { + if($i+1 >= $argc) { + Error("Argument to `-D' is missing"); + } + $macrodefn = $ARGV[++$i]; + } + # -Dmacro[=defn] format + else { + $macrodefn = substr($ARGV[$i], 2); + } + my $macro = $macrodefn; + my $defn = ""; + my $j = index($macrodefn, "="); + if($j > -1) { + $defn = substr($macrodefn, $j+1); + $macro = substr($macrodefn, 0, $j); + } + # add macro and defn to hash table + Define($macro." ".$defn); + } + + # Debugging turned on: -d + elsif($ARGV[$i] eq "-d") { + SetDebug(2); + } + + # Full debugging turned on: -dd + elsif($ARGV[$i] eq "-dd") { + SetDebug(3); + } + + # Light debugging turned on: -dl + elsif($ARGV[$i] eq "-dl") { + SetDebug(1); + } + + # Send debugging info to stdout rather than stderr + elsif($ARGV[$i] eq "-ds") { + $debugstdout = 1; + } + + # prefix all debugging info with string + elsif($ARGV[$i] eq "-dpre") { + if($i+1 >= $argc) { + Error("Argument to `-dpre' is missing"); + } + $debugprefix = ReplaceDefines($ARGV[++$i]); + } + + # prefix all debugging info with string + elsif($ARGV[$i] eq "-dpost") { + if($i+1 >= $argc) { + Error("Argument to `-dpost' is missing"); + } + # replace defines is called here in case a newline is required, + # this allows it to be added as __NEWLINE__ + $debugpostfix = ReplaceDefines($ARGV[++$i]); + } + + # define environment variables as macros: -e + elsif($ARGV[$i] eq "-e") { + DefineEnv(); + } + + # set environment variable prefix char + elsif($ARGV[$i] eq "-ec") { + if($i+1 >= $argc) { + Error("Argument to `-ec' is missing"); + } + SetEnvchar($ARGV[++$i]); + } + + # set environment variable prefix char to nothing + elsif($ARGV[$i] eq "-ecn") { + SetEnvchar(""); + } + + # show help + elsif($ARGV[$i] eq "-h") { + print(STDERR $usage); + exit(0); + } + + # Include paths: -Iinclude or -I include + elsif(substr($ARGV[$i], 0, 2) eq "-I") { + # -I include format + if(length($ARGV[$i]) == 2) { + if($i+1 >= $argc) { + Error("Argument to `-I' is missing"); + } + AddIncludePath($ARGV[++$i]); + } + # -Iinclude format + else { + AddIncludePath(substr($ARGV[$i], 2)); + } + } + + # Include macros from file: -imacros file + elsif($ARGV[$i] eq "-imacros") { + if($i+1 >= $argc) { + Error("Argument to `-imacros' is missing"); + } + push(@Imacrofiles, $ARGV[++$i]); + } + + # turn off keywords + elsif($ARGV[$i] eq "-k") { + RemoveAllKeywords(); + } + + # set keyword prefix char + elsif($ARGV[$i] eq "-kc") { + if($i+1 >= $argc) { + Error("Argument to `-kc' is missing"); + } + SetKeywordchar($ARGV[++$i]); + } + + # set line continuation character + elsif($ARGV[$i] eq "-lc") { + if($i+1 >= $argc) { + Error("Argument to `-lc' is missing"); + } + SetContchar($ARGV[++$i]); + } + + # set optional line end character + elsif($ARGV[$i] eq "-lec") { + if($i+1 >= $argc) { + Error("Argument to `-lec' is missing"); + } + SetOptLineEndchar($ARGV[++$i]); + } + + # set line continuation replacement char to newline + elsif($ARGV[$i] eq "-lrn") { + SetContrepchar("\n"); + } + + # set line continuation replacement character + elsif($ARGV[$i] eq "-lr") { + if($i+1 >= $argc) { + Error("Argument to `-lr' is missing"); + } + SetContrepchar($ARGV[++$i]); + } + + # Module paths: -Minclude or -M include + elsif(substr($ARGV[$i], 0, 2) eq "-M") { + # -M include format + if(length($ARGV[$i]) == 2) { + if($i+1 >= $argc) { + Error("Argument to `-M' is missing"); + } + AddModulePath($ARGV[++$i]); + } + # -Minclude format + else { + AddModulePath(substr($ARGV[$i], 2)); + } + } + + # use module + elsif($ARGV[$i] eq "-m") { + if($i+1 >= $argc) { + Error("Argument to `-m' is missing"); + } + UseModule($ARGV[++$i]); + } + + # set macro prefix + elsif($ARGV[$i] eq "-mp") { + if($i+1 >= $argc) { + Error("Argument to `-mp' is missing"); + } + SetMacroPrefix($ARGV[++$i]); + } + + # turn off macro prefix within keywords + elsif($ARGV[$i] eq "-mpnk") { + $macroprefixinkeywords = 0; + } + + # turn on overwrite mode + elsif($ARGV[$i] eq "-ov") { + $overwrite = 1; + } + + # turn on overwrite conversion mode + elsif($ARGV[$i] eq "-ovc") { + if($i+1 >= $argc) { + Error("Argument to `-ovc' is missing"); + } + $overwriteconv = $ARGV[++$i]; + if($overwriteconv !~ /=/) { + Error("-ovc argument is of form IN=OUT"); + } + $overwrite = 1; + } + + # Output filename: -o filename or -ofilename + elsif(substr($ARGV[$i], 0, 2) eq "-o") { + # -o filename + if(length($ARGV[$i]) == 2) { + if($i+1 >= $argc) { + Error("Argument to `-o' is missing"); + } + $outputfile = $ARGV[++$i]; + } + # -ofilename + else { + $outputfile = substr($ARGV[$i], 2); + } + } + + # preserve blank lines in output file + elsif($ARGV[$i] eq "-pb") { + $preserveblank = 1; + } + + # treat $keywordchar, $contchar and $optlineendchar as regular expressions + elsif($ARGV[$i] eq "-re") { + if($charperlre) { SetCharPerlre(0); } + else { SetCharPerlre(1); } + } + + # Safe mode - turns off #pragma + elsif($ARGV[$i] eq "-s") { + SafeMode(); + } + + # Undefine all macros + elsif($ARGV[$i] eq "-u") { + UndefAll(); + } + + # print version number and exit + elsif($ARGV[$i] eq "-v") { + print(STDERR "filepp version ".$VERSION."\n"); + exit(0); + } + + # only replace macros if they appear as 'words' + elsif($ARGV[$i] eq "-w") { + if($bound eq '') { SetWordBoundaries(1); } + else { SetWordBoundaries(0); } + } + + # default - an input file name + else { + if(!FileExists($ARGV[$i])) { + Error("Input file \"".$ARGV[$i]."\" not readable"); + } + AddInputFile($ARGV[$i]); + } + + $i++; + } + + # check input files have been specified + if($#Inputfiles == -1) { + Error("No input files given"); + } + + # import macros from file if any + if($#Imacrofiles >= 0) { + my $file; + foreach $file (@Imacrofiles) { IncludeMacros($file); } + } + + # print initial defines if debugging + if($debug > 1) { PrintDefines(); } + + # open the output file + if(!$overwrite) { OpenOutputFile($outputfile); } + + # parse all input files in order given on command line + my $base_file = ""; + foreach $base_file (@Inputfiles) { + Redefine("__BASE_FILE__", $base_file); + # set open output file if in overwrite mode + if($overwrite) { + if($overwriteconv ne "") { # convert output filename if needed + my ($in,$out) = split(/=/, $overwriteconv, 2); + my $outfile = $base_file; + $outfile =~ s/\Q$in\E/$out/; + OpenOutputFile($outfile); + } + else { OpenOutputFile($base_file); } + } + Parse($base_file); + # close output file if in overwrite mode + if($overwrite) { CloseOutputFile(); } + } + + # close output file + if(!$overwrite) { CloseOutputFile(); } + + exit(0); + + # Hey emacs !! + # Local Variables: + # mode: perl + # End: + + ######################################################################## + # End of file + ######################################################################## Index: llvm-test/Makefile.nagfortran diff -u llvm-test/Makefile.nagfortran:1.5 llvm-test/Makefile.nagfortran:1.6 --- llvm-test/Makefile.nagfortran:1.5 Mon Feb 27 16:11:35 2006 +++ llvm-test/Makefile.nagfortran Tue Feb 28 12:08:54 2006 @@ -39,13 +39,13 @@ $(F95) -w -S -O2 $< -o $@ $(NAGFORTRAN_FLAGS) %.f: %.F - $(CPP) -x c $< -o - $(CPPFLAGS) -traditional-cpp | $(SED) '/^# /d' > $@ + $(LEVEL)/filepp $< -o $@ -M $(SPEC_BENCH_DIR)/src/ $(FPPFLAGS) %.c: %.f90 $(F95) -w -S -O2 $< -o $@ $(NAGFORTRAN_FLAGS) %.f90: %.F90 - $(CPP) -x c $< -o - $(CPPFLAGS) -traditional-cpp | $(SED) '/^# /d' > $@ + $(LEVEL)/filepp $< -o $@ -M $(SPEC_BENCH_DIR)/src/ $(FPPFLAGS) CPPFLAGS += -I$(F95_DIR)/lib/NAGWare LDFLAGS += $(F95_DIR)/lib/NAGWare/quickfit.o -Xlinker -flat_namespace $(F95_DIR)/lib/NAGWare/libf97.dylib $(F95_DIR)/lib/NAGWare/libf96.a From natebegeman at mac.com Tue Feb 28 12:22:37 2006 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 28 Feb 2006 12:22:37 -0600 Subject: [llvm-commits] CVS: llvm-test/Makefile.rules Message-ID: <200602281822.MAA10660@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.rules updated: 1.8 -> 1.9 --- Log message: Use the input LLVMGCC/LLVMGXX variables set by Makefile.config instead of creating our own. Creating our own breaks symlinks. --- Diffs of the changes: (+2 -2) Makefile.rules | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-test/Makefile.rules diff -u llvm-test/Makefile.rules:1.8 llvm-test/Makefile.rules:1.9 --- llvm-test/Makefile.rules:1.8 Tue Mar 8 16:58:33 2005 +++ llvm-test/Makefile.rules Tue Feb 28 12:22:24 2006 @@ -252,8 +252,8 @@ #-------------------------------------------------------------------------- # The LLVM GCC front-end in C and C++ flavors # -LLVMGCC := PATH="$(LLVMTOOLCURRENT):$(PATH)" $(LLVMGCCDIR)/bin/llvm-gcc -LLVMGXX := PATH="$(LLVMTOOLCURRENT):$(PATH)" $(LLVMGCCDIR)/bin/llvm-g++ +LLVMGCC := PATH="$(LLVMTOOLCURRENT):$(PATH)" $(LLVMGCC) +LLVMGXX := PATH="$(LLVMTOOLCURRENT):$(PATH)" $(LLVMGXX) #-------------------------------------------------------------------------- # The compiled LLVM tools From lattner at cs.uiuc.edu Tue Feb 28 13:13:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 13:13:10 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200602281913.NAA10944@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.347 -> 1.348 --- Log message: 8 spaces -> tab. Reported by Wink Saville --- Diffs of the changes: (+1 -1) Makefile.rules | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.347 llvm/Makefile.rules:1.348 --- llvm/Makefile.rules:1.347 Wed Feb 15 23:10:48 2006 +++ llvm/Makefile.rules Tue Feb 28 13:12:58 2006 @@ -1096,7 +1096,7 @@ ifdef DEBUG_RUNTIME $(ObjectsBC): $(ObjDir)/%.bc: $(ObjDir)/%.ll $(GCCAS) $(Echo) "Compiling $*.ll to $*.bc for $(BuildMode) build (bytecode)" - @$(GCCAS) $< -o $@ + @$(GCCAS) $< -o $@ else $(ObjectsBC): $(ObjDir)/%.bc: $(ObjDir)/%.ll $(GCCAS) $(Echo) "Compiling $*.ll to $*.bc for $(BuildMode) build (bytecode)" From lattner at cs.uiuc.edu Tue Feb 28 13:47:09 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 13:47:09 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2006-02-28-Crash.ll Message-ID: <200602281947.NAA11228@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2006-02-28-Crash.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+6 -0) 2006-02-28-Crash.ll | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/2006-02-28-Crash.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2006-02-28-Crash.ll:1.1 *** /dev/null Tue Feb 28 13:47:06 2006 --- llvm/test/Regression/Transforms/InstCombine/2006-02-28-Crash.ll Tue Feb 28 13:46:56 2006 *************** *** 0 **** --- 1,6 ---- + ; RUN: llvm-as < %s | opt -instcombine -disable-output + int %test() { + %tmp203 = seteq uint 1, 2 ; [#uses=1] + %tmp203 = cast bool %tmp203 to int ; [#uses=1] + ret int %tmp203 + } From lattner at cs.uiuc.edu Tue Feb 28 13:47:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 13:47:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200602281947.NAA11263@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.444 -> 1.445 --- Log message: Fix a regression in a patch from a couple of days ago. This fixes Transforms/InstCombine/2006-02-28-Crash.ll --- Diffs of the changes: (+3 -1) InstructionCombining.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.444 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.445 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.444 Mon Feb 27 23:49:21 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 28 13:47:20 2006 @@ -4818,7 +4818,9 @@ if (Op1CV && (Op1CV != (KnownZero^TypeMask))) { // (X&4) == 2 --> false // (X&4) != 2 --> true - return ReplaceInstUsesWith(CI, ConstantBool::get(isSetNE)); + Constant *Res = ConstantBool::get(isSetNE); + Res = ConstantExpr::getCast(Res, CI.getType()); + return ReplaceInstUsesWith(CI, Res); } unsigned ShiftAmt = Log2_64(KnownZero^TypeMask); From jlaskey at apple.com Tue Feb 28 14:15:20 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 28 Feb 2006 14:15:20 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200602282015.OAA11388@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.21 -> 1.22 --- Log message: Add const, volatile, restrict support. Add array of debug descriptor support. --- Diffs of the changes: (+15 -3) MachineDebugInfo.h | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.21 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.22 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.21 Fri Feb 24 10:46:40 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Tue Feb 28 14:15:07 2006 @@ -66,7 +66,10 @@ DI_TAG_basictype, DI_TAG_typedef, DI_TAG_pointer, - DI_TAG_reference + DI_TAG_reference, + DI_TAG_const, + DI_TAG_volatile, + DI_TAG_restrict }; //===----------------------------------------------------------------------===// @@ -90,6 +93,7 @@ virtual void Apply(std::string &Field) = 0; virtual void Apply(DebugInfoDesc *&Field) = 0; virtual void Apply(GlobalVariable *&Field) = 0; + virtual void Apply(std::vector &Field) = 0; }; //===----------------------------------------------------------------------===// @@ -148,7 +152,6 @@ #endif }; - //===----------------------------------------------------------------------===// /// AnchorDesc - Descriptors of this class act as markers for identifying /// descriptors of certain groups. @@ -371,7 +374,16 @@ static bool classof(const DerivedTypeDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { unsigned T = D->getTag(); - return T == DI_TAG_typedef || T == DI_TAG_pointer || T == DI_TAG_reference; + switch (T) { + case DI_TAG_typedef: + case DI_TAG_pointer: + case DI_TAG_reference: + case DI_TAG_const: + case DI_TAG_volatile: + case DI_TAG_restrict: + return true; + default: return false; + } } /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. From jlaskey at apple.com Tue Feb 28 14:15:20 2006 From: jlaskey at apple.com (Jim Laskey) Date: Tue, 28 Feb 2006 14:15:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200602282015.OAA11384@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.34 -> 1.35 MachineDebugInfo.cpp updated: 1.18 -> 1.19 --- Log message: Add const, volatile, restrict support. Add array of debug descriptor support. --- Diffs of the changes: (+67 -5) DwarfWriter.cpp | 3 ++ MachineDebugInfo.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.34 llvm/lib/CodeGen/DwarfWriter.cpp:1.35 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.34 Mon Feb 27 16:37:23 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Tue Feb 28 14:15:07 2006 @@ -1075,6 +1075,9 @@ case DI_TAG_typedef: T = DW_TAG_typedef; break; case DI_TAG_pointer: T = DW_TAG_pointer_type; break; case DI_TAG_reference: T = DW_TAG_reference_type; break; + case DI_TAG_const: T = DW_TAG_const_type; break; + case DI_TAG_volatile: T = DW_TAG_volatile_type; break; + case DI_TAG_restrict: T = DW_TAG_restrict_type; break; default: assert( 0 && "Unknown tag on derived type"); } Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.18 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.19 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.18 Fri Feb 24 10:46:40 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Tue Feb 28 14:15:07 2006 @@ -202,6 +202,9 @@ virtual void Apply(std::string &Field) { ++Count; } virtual void Apply(DebugInfoDesc *&Field) { ++Count; } virtual void Apply(GlobalVariable *&Field) { ++Count; } + virtual void Apply(std::vector &Field) { + ++Count; + } }; //===----------------------------------------------------------------------===// @@ -251,6 +254,17 @@ Constant *C = CI->getOperand(I++); Field = getGlobalVariable(C); } + virtual void Apply(std::vector &Field) { + Constant *C = CI->getOperand(I++); + GlobalVariable *GV = getGlobalVariable(C); + ConstantArray *CA = cast(GV->getInitializer()); + Field.resize(0); + for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) { + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + DebugInfoDesc *DE = DR.Deserialize(GVE); + Field.push_back(DE); + } + } }; //===----------------------------------------------------------------------===// @@ -310,6 +324,22 @@ Elements.push_back(ConstantPointerNull::get(EmptyTy)); } } + virtual void Apply(std::vector &Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + unsigned N = Field.size(); + ArrayType *AT = ArrayType::get(EmptyTy, N); + std::vector ArrayElements; + + for (unsigned i = 0, N = Field.size(); i < N; ++i) { + GlobalVariable *GVE = SR.Serialize(Field[i]); + Constant *CE = ConstantExpr::getCast(GVE, EmptyTy); + ArrayElements.push_back(cast(CE)); + } + + Constant *CA = ConstantArray::get(AT, ArrayElements); + Constant *CAE = ConstantExpr::getCast(CA, EmptyTy); + Elements.push_back(CAE); + } }; //===----------------------------------------------------------------------===// @@ -353,6 +383,10 @@ const PointerType *EmptyTy = SR.getEmptyStructPtrType(); Fields.push_back(EmptyTy); } + virtual void Apply(std::vector &Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + Fields.push_back(EmptyTy); + } }; //===----------------------------------------------------------------------===// @@ -409,6 +443,27 @@ Constant *C = CI->getOperand(I++); IsValid = IsValid && isGlobalVariable(C); } + virtual void Apply(std::vector &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + if (!IsValid) return; + + GlobalVariable *GV = getGlobalVariable(C); + IsValid = IsValid && GV && GV->hasInitializer(); + if (!IsValid) return; + + ConstantArray *CA = dyn_cast(GV->getInitializer()); + IsValid = IsValid && CA; + if (!IsValid) return; + + for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) { + IsValid = IsValid && isGlobalVariable(CA->getOperand(i)); + if (!IsValid) return; + + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + VR.Verify(GVE); + } + } }; @@ -430,9 +485,12 @@ case DI_TAG_global_variable: return new GlobalVariableDesc(); case DI_TAG_subprogram: return new SubprogramDesc(); case DI_TAG_basictype: return new BasicTypeDesc(); - case DI_TAG_typedef: return new DerivedTypeDesc(DI_TAG_typedef); - case DI_TAG_pointer: return new DerivedTypeDesc(DI_TAG_pointer); - case DI_TAG_reference: return new DerivedTypeDesc(DI_TAG_reference); + case DI_TAG_typedef: + case DI_TAG_pointer: + case DI_TAG_reference: + case DI_TAG_const: + case DI_TAG_volatile: + case DI_TAG_restrict: return new DerivedTypeDesc(Tag); default: break; } return NULL; @@ -639,8 +697,7 @@ : TypeDesc(T) , FromType(NULL) { - assert((T == DI_TAG_typedef || T == DI_TAG_pointer || T == DI_TAG_reference)&& - "Unknown derived type."); + assert(classof((const DebugInfoDesc *)this) && "Unknown derived type."); } /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. @@ -777,6 +834,8 @@ } #endif +//===----------------------------------------------------------------------===// + DebugInfoDesc *DIDeserializer::Deserialize(Value *V) { return Deserialize(getGlobalVariable(V)); } From evan.cheng at apple.com Tue Feb 28 15:14:09 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 15:14:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200602282114.PAA11614@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.54 -> 1.55 --- Log message: Don't match x << 1 to LEAL. It's better to emit x + x. --- Diffs of the changes: (+4 -1) X86ISelDAGToDAG.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.54 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.55 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.54 Sat Feb 25 04:09:08 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Feb 28 15:13:57 2006 @@ -453,8 +453,11 @@ else AM.IndexReg = CurDAG->getRegister(0, MVT::i32); - if (AM.Scale > 1) + if (AM.Scale > 2) Complexity += 2; + // Don't match just leal(,%reg,2). It's cheaper to do addl %reg, %reg + else if (AM.Scale > 1) + Complexity++; // FIXME: We are artificially lowering the criteria to turn ADD %reg, $GA // to a LEA. This is determined with some expermentation but is by no means From evan.cheng at apple.com Tue Feb 28 17:39:02 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 17:39:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602282339.RAA13268@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.61 -> 1.62 --- Log message: Another entry. --- Diffs of the changes: (+16 -0) README.txt | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.61 llvm/lib/Target/X86/README.txt:1.62 --- llvm/lib/Target/X86/README.txt:1.61 Sat Feb 25 04:04:07 2006 +++ llvm/lib/Target/X86/README.txt Tue Feb 28 17:38:49 2006 @@ -517,3 +517,19 @@ //===---------------------------------------------------------------------===// Enable X86InstrInfo::convertToThreeAddress(). + +//===---------------------------------------------------------------------===// + +Investigate whether it is better to codegen the following + + %tmp.1 = mul int %x, 9 +to + + movl 4(%esp), %eax + leal (%eax,%eax,8), %eax + +as opposed to what llc is currently generating: + + imull $9, 4(%esp), %eax + +Currently the load folding imull has a higher complexity than the LEA32 pattern. From evan.cheng at apple.com Tue Feb 28 17:57:58 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 17:57:58 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/shift-one.ll Message-ID: <200602282357.RAA13497@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: shift-one.ll added (r1.1) --- Log message: Add a test case for left shift by 1. We should not be using lea for this. --- Diffs of the changes: (+9 -0) shift-one.ll | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Regression/CodeGen/X86/shift-one.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/shift-one.ll:1.1 *** /dev/null Tue Feb 28 17:57:55 2006 --- llvm/test/Regression/CodeGen/X86/shift-one.ll Tue Feb 28 17:57:45 2006 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | llc -march=x86 | not grep 'leal' + + %x = external global int + + int %test() { + %tmp.0 = load int* %x + %tmp.1 = shl int %tmp.0, ubyte 1 + ret int %tmp.1 + } From evan.cheng at apple.com Tue Feb 28 18:51:26 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 18:51:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200603010051.SAA13713@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.261 -> 1.262 --- Log message: - Added VConstant as an abstract version of ConstantVec. - All abstrct vector nodes must have # of elements and element type as their first two operands. --- Diffs of the changes: (+19 -12) SelectionDAG.cpp | 31 +++++++++++++++++++------------ 1 files changed, 19 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.261 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.262 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.261 Sun Feb 26 02:36:57 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Feb 28 18:51:13 2006 @@ -1400,10 +1400,10 @@ if (N) return SDOperand(N, 0); std::vector Ops; Ops.reserve(5); - Ops.push_back(Chain); - Ops.push_back(Ptr); Ops.push_back(getConstant(Count, MVT::i32)); Ops.push_back(getValueType(EVT)); + Ops.push_back(Chain); + Ops.push_back(Ptr); Ops.push_back(SV); std::vector VTs; VTs.reserve(2); @@ -2557,26 +2557,33 @@ case ISD::PCMARKER: return "PCMarker"; case ISD::READCYCLECOUNTER: return "ReadCycleCounter"; case ISD::SRCVALUE: return "SrcValue"; - case ISD::VALUETYPE: return "ValueType"; - case ISD::STRING: return "String"; case ISD::EntryToken: return "EntryToken"; case ISD::TokenFactor: return "TokenFactor"; case ISD::AssertSext: return "AssertSext"; case ISD::AssertZext: return "AssertZext"; + + case ISD::STRING: return "String"; + case ISD::BasicBlock: return "BasicBlock"; + case ISD::VALUETYPE: return "ValueType"; + case ISD::Register: return "Register"; + case ISD::Constant: return "Constant"; - case ISD::TargetConstant: return "TargetConstant"; case ISD::ConstantFP: return "ConstantFP"; - case ISD::ConstantVec: return "ConstantVec"; case ISD::GlobalAddress: return "GlobalAddress"; - case ISD::TargetGlobalAddress: return "TargetGlobalAddress"; case ISD::FrameIndex: return "FrameIndex"; - case ISD::TargetFrameIndex: return "TargetFrameIndex"; - case ISD::BasicBlock: return "BasicBlock"; - case ISD::Register: return "Register"; - case ISD::ExternalSymbol: return "ExternalSymbol"; - case ISD::TargetExternalSymbol: return "TargetExternalSymbol"; case ISD::ConstantPool: return "ConstantPool"; + case ISD::ExternalSymbol: return "ExternalSymbol"; + + case ISD::ConstantVec: return "ConstantVec"; + case ISD::TargetConstant: return "TargetConstant"; + case ISD::TargetConstantFP:return "TargetConstantFP"; + case ISD::TargetConstantVec:return "TargetConstantVec"; + case ISD::TargetGlobalAddress: return "TargetGlobalAddress"; + case ISD::TargetFrameIndex: return "TargetFrameIndex"; case ISD::TargetConstantPool: return "TargetConstantPool"; + case ISD::TargetExternalSymbol: return "TargetExternalSymbol"; + case ISD::VConstant: return "VConstant"; + case ISD::CopyToReg: return "CopyToReg"; case ISD::CopyFromReg: return "CopyFromReg"; case ISD::UNDEF: return "undef"; From evan.cheng at apple.com Tue Feb 28 18:51:26 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 18:51:26 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200603010051.SAA13709@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.104 -> 1.105 --- Log message: - Added VConstant as an abstract version of ConstantVec. - All abstrct vector nodes must have # of elements and element type as their first two operands. --- Diffs of the changes: (+15 -10) SelectionDAGNodes.h | 25 +++++++++++++++---------- 1 files changed, 15 insertions(+), 10 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.104 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.105 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.104 Sat Feb 25 03:52:55 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Tue Feb 28 18:51:13 2006 @@ -63,10 +63,10 @@ AssertSext, AssertZext, // Various leaf nodes. - Constant, ConstantFP, STRING, - GlobalAddress, FrameIndex, ConstantPool, - BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register, - + STRING, BasicBlock, VALUETYPE, CONDCODE, Register, + Constant, ConstantFP, + GlobalAddress, FrameIndex, ConstantPool, ExternalSymbol, + // ConstantVec works like Constant or ConstantFP, except that it is not a // leaf node. All operands are either Constant or ConstantFP nodes. ConstantVec, @@ -85,6 +85,11 @@ TargetConstantPool, TargetExternalSymbol, + // Abstract version of ConstantVec with abstract Vector type. The first node + // is a constant element count, the second is a value type indicating the + // type of the elements. + VConstant, + // CopyToReg - This node has three operands: a chain, a register number to // set to this value, and a value. CopyToReg, @@ -139,9 +144,9 @@ // Simple abstract vector operators. Unlike the integer and floating point // binary operators, these nodes also take two additional operands: // a constant element count, and a value type node indicating the type of - // the elements. The order is op0, op1, count, type. All vector opcodes, - // including VLOAD, must currently have count and type as their 3rd and 4th - // arguments. + // the elements. The order is count, type, op0, op1. All vector opcodes, + // including VLOAD and VConstant must currently have count and type as + // their 1st and 2nd arguments. VADD, VSUB, VMUL, // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing @@ -243,9 +248,9 @@ // SRCVALUE node that provides alias analysis information. LOAD, STORE, - // Abstract vector version of LOAD. VLOAD has a token chain as the first - // operand, followed by a pointer operand, a constant element count, a value - // type node indicating the type of the elements, and a SRCVALUE node. + // Abstract vector version of LOAD. VLOAD has a constant element count as + // the first operand, followed by a value type node indicating the type of + // the elements, a token chain, a pointer operand, and a SRCVALUE node. VLOAD, // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from From evan.cheng at apple.com Tue Feb 28 18:55:38 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 18:55:38 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200603010055.SAA13729@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.19 -> 1.20 --- Log message: - Added v2f32, not used by any target currently. Only for testing purpose. - Minor bug fix. --- Diffs of the changes: (+27 -12) ValueTypes.h | 39 +++++++++++++++++++++++++++------------ 1 files changed, 27 insertions(+), 12 deletions(-) Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.19 llvm/include/llvm/CodeGen/ValueTypes.h:1.20 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.19 Wed Feb 22 10:23:43 2006 +++ llvm/include/llvm/CodeGen/ValueTypes.h Tue Feb 28 18:55:26 2006 @@ -56,20 +56,21 @@ v4i32 = 19, // 4 x i32 v2i64 = 20, // 2 x i64 - v4f32 = 21, // 4 x f32 - v2f64 = 22, // 2 x f64 + v2f32 = 21, // 2 x f32 + v4f32 = 22, // 4 x f32 + v2f64 = 23, // 2 x f64 LAST_VALUETYPE // This always remains at the end of the list. }; static inline bool isInteger(ValueType VT) { - return (VT >= i1 && VT <= i128) || (VT >= v16i8 && VT <= v2i64); + return (VT >= i1 && VT <= i128) || (VT >= v8i8 && VT <= v2i64); } static inline bool isFloatingPoint(ValueType VT) { return (VT >= f32 && VT <= f128) || (VT >= v4f32 && VT <= v2f64); } static inline bool isVector(ValueType VT) { - return (VT >= v16i8 && VT <= v2f64); + return (VT >= v8i8 && VT <= v2f64); } /// getVectorType - Returns the ValueType that represents a vector NumElements @@ -80,11 +81,24 @@ switch (VT) { default: break; + case MVT::i8: + if (NumElements == 8) return MVT::v8i8; + if (NumElements == 16) return MVT::v16i8; + break; + case MVT::i16: + if (NumElements == 4) return MVT::v4i16; + if (NumElements == 8) return MVT::v8i16; + break; case MVT::i32: - if (NumElements == 4) return MVT::v4i32; + if (NumElements == 2) return MVT::v2i32; + if (NumElements == 4) return MVT::v4i32; break; case MVT::f32: - if (NumElements == 4) return MVT::v4f32; + if (NumElements == 2) return MVT::v2f32; + if (NumElements == 4) return MVT::v4f32; + break; + case MVT::f64: + if (NumElements == 2) return MVT::v2f64; break; } return MVT::Other; @@ -93,17 +107,18 @@ static inline unsigned getSizeInBits(ValueType VT) { switch (VT) { default: assert(0 && "ValueType has no known size!"); - case MVT::i1 : return 1; - case MVT::i8 : return 8; - case MVT::i16 : return 16; + case MVT::i1 : return 1; + case MVT::i8 : return 8; + case MVT::i16 : return 16; case MVT::f32 : - case MVT::i32 : return 32; + case MVT::i32 : return 32; case MVT::f64 : case MVT::i64 : case MVT::v8i8: case MVT::v4i16: - case MVT::v2i32:return 64; - case MVT::f80 : return 80; + case MVT::v2i32: + case MVT::v2f32: return 64; + case MVT::f80 : return 80; case MVT::f128: case MVT::i128: case MVT::v16i8: From evan.cheng at apple.com Tue Feb 28 18:59:06 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 18:59:06 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200603010059.SAA13743@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.55 -> 1.56 --- Log message: Missing a cast previously. --- Diffs of the changes: (+1 -1) TargetLowering.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.55 llvm/include/llvm/Target/TargetLowering.h:1.56 --- llvm/include/llvm/Target/TargetLowering.h:1.55 Thu Feb 23 19:10:14 2006 +++ llvm/include/llvm/Target/TargetLowering.h Tue Feb 28 18:58:54 2006 @@ -412,7 +412,7 @@ assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) && "Table isn't big enough!"); OpActions[Op] &= ~(3ULL << VT*2); - OpActions[Op] |= Action << VT*2; + OpActions[Op] |= (uint64_t)Action << VT*2; } /// addLegalFPImmediate - Indicate that this target can instruction select From evan.cheng at apple.com Tue Feb 28 19:06:35 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 19:06:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200603010106.TAA13821@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.71 -> 1.72 --- Log message: New type v2f32. --- Diffs of the changes: (+3 -2) Target.td | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.71 llvm/lib/Target/Target.td:1.72 --- llvm/lib/Target/Target.td:1.71 Mon Feb 20 16:34:53 2006 +++ llvm/lib/Target/Target.td Tue Feb 28 19:06:22 2006 @@ -46,8 +46,9 @@ def v8i16 : ValueType<128, 18>; // 8 x i16 vector value def v4i32 : ValueType<128, 19>; // 4 x i32 vector value def v2i64 : ValueType<128, 20>; // 2 x i64 vector value -def v4f32 : ValueType<128, 21>; // 4 x f32 vector value -def v2f64 : ValueType<128, 22>; // 2 x f64 vector value +def v2f32 : ValueType<64, 21>; // 2 x f32 vector value +def v4f32 : ValueType<128, 22>; // 4 x f32 vector value +def v2f64 : ValueType<128, 23>; // 2 x f64 vector value //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target From evan.cheng at apple.com Tue Feb 28 19:10:06 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 19:10:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200603010110.TAA13859@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.113 -> 1.114 LegalizeDAG.cpp updated: 1.307 -> 1.308 SelectionDAGISel.cpp updated: 1.174 -> 1.175 --- Log message: Vector ops lowering. --- Diffs of the changes: (+76 -50) DAGCombiner.cpp | 2 LegalizeDAG.cpp | 110 ++++++++++++++++++++++++++++++--------------------- SelectionDAGISel.cpp | 14 ++++-- 3 files changed, 76 insertions(+), 50 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.113 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.114 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.113 Tue Feb 28 00:49:37 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 19:09:54 2006 @@ -663,7 +663,7 @@ if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1)) return N1.getOperand(0); // - if (SimplifyDemandedBits(SDOperand(N, 0))) + if (!MVT::isVector(VT) && SimplifyDemandedBits(SDOperand(N, 0))) return SDOperand(); return SDOperand(); } Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.307 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.308 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.307 Mon Feb 20 00:38:35 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Feb 28 19:09:54 2006 @@ -1306,8 +1306,8 @@ // in the high half of the vector. unsigned IncrementSize; if (MVT::Vector == Hi.getValueType()) { - unsigned NumElems = cast(Hi.getOperand(2))->getValue(); - MVT::ValueType EVT = cast(Hi.getOperand(3))->getVT(); + unsigned NumElems = cast(Hi.getOperand(0))->getValue(); + MVT::ValueType EVT = cast(Hi.getOperand(1))->getVT(); IncrementSize = NumElems * MVT::getSizeInBits(EVT)/8; } else { IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8; @@ -3529,25 +3529,39 @@ Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT); break; } - case ISD::ConstantVec: { - unsigned NumElements = Node->getNumOperands(); - // If we only have two elements left in the constant vector, just break it - // apart into the two scalar constants it contains. Otherwise, bisect the - // ConstantVec, and return each half as a new ConstantVec. - // FIXME: this is hard coded as big endian, it may have to change to support - // SSE and Alpha MVI - if (NumElements == 2) { - Hi = Node->getOperand(0); - Lo = Node->getOperand(1); + case ISD::VConstant: { + unsigned NumElements = + cast(Node->getOperand(0))->getValue() / 2; + MVT::ValueType EVT = cast(Node->getOperand(1))->getVT(); + MVT::ValueType TVT = (NumElements > 1) + ? getVectorType(EVT, NumElements) : EVT; + // If type of bisected vector is legal, turn it into a ConstantVec (which + // will be lowered to a ConstantPool or something else). Otherwise, bisect + // the VConstant, and return each half as a new VConstant. + unsigned Opc = ISD::ConstantVec; + std::vector LoOps, HiOps; + if (!(TVT != MVT::Other && + (!MVT::isVector(TVT) || TLI.isTypeLegal(TVT)))) { + Opc = ISD::VConstant; + TVT = MVT::Vector; + SDOperand Num = DAG.getConstant(NumElements, MVT::i32); + SDOperand Typ = DAG.getValueType(EVT); + HiOps.push_back(Num); + HiOps.push_back(Typ); + LoOps.push_back(Num); + LoOps.push_back(Typ); + } + + if (NumElements == 1) { + Hi = Node->getOperand(2); + Lo = Node->getOperand(3); } else { - NumElements /= 2; - std::vector LoOps, HiOps; for (unsigned I = 0, E = NumElements; I < E; ++I) { - HiOps.push_back(Node->getOperand(I)); - LoOps.push_back(Node->getOperand(I+NumElements)); + HiOps.push_back(Node->getOperand(I+2)); + LoOps.push_back(Node->getOperand(I+2+NumElements)); } - Lo = DAG.getNode(ISD::ConstantVec, MVT::Vector, LoOps); - Hi = DAG.getNode(ISD::ConstantVec, MVT::Vector, HiOps); + Hi = DAG.getNode(Opc, TVT, HiOps); + Lo = DAG.getNode(Opc, TVT, LoOps); } break; } @@ -3652,22 +3666,25 @@ break; } case ISD::VLOAD: { - SDOperand Ch = Node->getOperand(0); // Legalize the chain. - SDOperand Ptr = Node->getOperand(1); // Legalize the pointer. - unsigned NumElements =cast(Node->getOperand(2))->getValue(); - MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); - - // If we only have two elements, turn into a pair of scalar loads. - // FIXME: handle case where a vector of two elements is fine, such as - // 2 x double on SSE2. - if (NumElements == 2) { - Lo = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4)); + SDOperand Ch = Node->getOperand(2); // Legalize the chain. + SDOperand Ptr = Node->getOperand(3); // Legalize the pointer. + unsigned NumElements =cast(Node->getOperand(0))->getValue(); + MVT::ValueType EVT = cast(Node->getOperand(1))->getVT(); + MVT::ValueType TVT = (NumElements/2 > 1) + ? getVectorType(EVT, NumElements/2) : EVT; + + // If type of split vector is legal, turn into a pair of scalar or + // packed loads. + if (TVT != MVT::Other && + (!MVT::isVector(TVT) || + (TLI.isTypeLegal(TVT) && TLI.isOperationLegal(ISD::LOAD, TVT)))) { + Lo = DAG.getLoad(TVT, Ch, Ptr, Node->getOperand(4)); // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(EVT)/8; + unsigned IncrementSize = MVT::getSizeInBits(TVT)/8; Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); // FIXME: This creates a bogus srcvalue! - Hi = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4)); + Hi = DAG.getLoad(TVT, Ch, Ptr, Node->getOperand(4)); } else { NumElements /= 2; // Split the vector in half Lo = DAG.getVecLoad(NumElements, EVT, Ch, Ptr, Node->getOperand(4)); @@ -3692,25 +3709,28 @@ case ISD::VADD: case ISD::VSUB: case ISD::VMUL: { - unsigned NumElements =cast(Node->getOperand(2))->getValue(); - MVT::ValueType EVT = cast(Node->getOperand(3))->getVT(); + unsigned NumElements =cast(Node->getOperand(0))->getValue(); + MVT::ValueType EVT = cast(Node->getOperand(1))->getVT(); + MVT::ValueType TVT = (NumElements/2 > 1) + ? getVectorType(EVT, NumElements/2) : EVT; SDOperand LL, LH, RL, RH; - ExpandOp(Node->getOperand(0), LL, LH); - ExpandOp(Node->getOperand(1), RL, RH); + ExpandOp(Node->getOperand(2), LL, LH); + ExpandOp(Node->getOperand(3), RL, RH); - // If we only have two elements, turn into a pair of scalar loads. - // FIXME: handle case where a vector of two elements is fine, such as - // 2 x double on SSE2. - if (NumElements == 2) { - unsigned Opc = getScalarizedOpcode(Node->getOpcode(), EVT); - Lo = DAG.getNode(Opc, EVT, LL, RL); - Hi = DAG.getNode(Opc, EVT, LH, RH); + // If type of split vector is legal, turn into a pair of scalar / packed + // ADD, SUB, or MUL. + unsigned Opc = getScalarizedOpcode(Node->getOpcode(), EVT); + if (TVT != MVT::Other && + (!MVT::isVector(TVT) || + (TLI.isTypeLegal(TVT) && TLI.isOperationLegal(Opc, TVT)))) { + Lo = DAG.getNode(Opc, TVT, LL, RL); + Hi = DAG.getNode(Opc, TVT, LH, RH); } else { - Lo = DAG.getNode(Node->getOpcode(), MVT::Vector, LL, RL, LL.getOperand(2), - LL.getOperand(3)); - Hi = DAG.getNode(Node->getOpcode(), MVT::Vector, LH, RH, LH.getOperand(2), - LH.getOperand(3)); + SDOperand Num = DAG.getConstant(NumElements/2, MVT::i32); + SDOperand Typ = DAG.getValueType(EVT); + Lo = DAG.getNode(Node->getOpcode(), MVT::Vector, Num, Typ, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), MVT::Vector, Num, Typ, LH, RH); } break; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.174 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.175 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.174 Mon Feb 27 17:45:39 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Feb 28 19:09:54 2006 @@ -415,7 +415,11 @@ } else { // If the packed type isn't legal, then create a ConstantVec node with // generic Vector type instead. - return N = DAG.getNode(ISD::ConstantVec, MVT::Vector, Ops); + SDOperand Num = DAG.getConstant(NumElements, MVT::i32); + SDOperand Typ = DAG.getValueType(PVT); + Ops.insert(Ops.begin(), Typ); + Ops.insert(Ops.begin(), Num); + return N = DAG.getNode(ISD::VConstant, MVT::Vector, Ops); } } else { // Canonicalize all constant ints to be unsigned. @@ -668,12 +672,13 @@ unsigned Opc = MVT::isFloatingPoint(PVT) ? FPOp : IntOp; if (NumElements == 1) { setValue(&I, DAG.getNode(Opc, PVT, Op1, Op2)); - } else if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) { + } else if (TVT != MVT::Other && + TLI.isTypeLegal(TVT) && TLI.isOperationLegal(Opc, TVT)) { setValue(&I, DAG.getNode(Opc, TVT, Op1, Op2)); } else { SDOperand Num = DAG.getConstant(NumElements, MVT::i32); SDOperand Typ = DAG.getValueType(PVT); - setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ)); + setValue(&I, DAG.getNode(VecOp, MVT::Vector, Num, Typ, Op1, Op2)); } } } @@ -905,7 +910,8 @@ // the Legalize pass does not have to deal with them. if (NumElements == 1) { L = DAG.getLoad(PVT, Root, Ptr, DAG.getSrcValue(I.getOperand(0))); - } else if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) { + } else if (TVT != MVT::Other && + TLI.isTypeLegal(TVT) && TLI.isOperationLegal(ISD::LOAD, TVT)) { L = DAG.getLoad(TVT, Root, Ptr, DAG.getSrcValue(I.getOperand(0))); } else { L = DAG.getVecLoad(NumElements, PVT, Root, Ptr, From evan.cheng at apple.com Tue Feb 28 19:11:05 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 19:11:05 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp Message-ID: <200603010111.TAA13878@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.55 -> 1.56 --- Log message: New vector type v2f32. --- Diffs of the changes: (+2 -0) CodeGenTarget.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.55 llvm/utils/TableGen/CodeGenTarget.cpp:1.56 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.55 Mon Feb 20 16:34:53 2006 +++ llvm/utils/TableGen/CodeGenTarget.cpp Tue Feb 28 19:10:52 2006 @@ -54,6 +54,7 @@ case MVT::v8i16: return "v8i16"; case MVT::v4i32: return "v4i32"; case MVT::v2i64: return "v2i64"; + case MVT::v2f32: return "v2f32"; case MVT::v4f32: return "v4f32"; case MVT::v2f64: return "v2f64"; default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; @@ -79,6 +80,7 @@ case MVT::v8i16: return "v8i16"; case MVT::v4i32: return "v4i32"; case MVT::v2i64: return "v2i64"; + case MVT::v2f32: return "v2f32"; case MVT::v4f32: return "v4f32"; case MVT::v2f64: return "v2f64"; default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; From evan.cheng at apple.com Tue Feb 28 19:11:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 19:11:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200603010111.TAA13899@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.91 -> 1.92 --- Log message: Vector op lowering. --- Diffs of the changes: (+16 -0) PPCISelLowering.cpp | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.91 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.92 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.91 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Feb 28 19:11:20 2006 @@ -156,10 +156,26 @@ setOperationAction(ISD::SRA, MVT::i64, Custom); } + // First set operation action for all vector types to expand. Then we + // will selectively turn on ones that can be effectively codegen'd. + for (unsigned VT = (unsigned)MVT::Vector + 1; + VT != (unsigned)MVT::LAST_VALUETYPE; VT++) { + setOperationAction(ISD::ADD , (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand); + setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand); + setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand); + } + if (TM.getSubtarget().hasAltivec()) { addRegisterClass(MVT::v4f32, PPC::VRRCRegisterClass); addRegisterClass(MVT::v4i32, PPC::VRRCRegisterClass); + setOperationAction(ISD::ADD , MVT::v4f32, Legal); + setOperationAction(ISD::SUB , MVT::v4f32, Legal); + setOperationAction(ISD::MUL , MVT::v4f32, Legal); + setOperationAction(ISD::LOAD , MVT::v4f32, Legal); + setOperationAction(ISD::ADD , MVT::v4i32, Legal); + setOperationAction(ISD::LOAD , MVT::v4i32, Legal); // FIXME: We don't support any ConstantVec's yet. We should custom expand // the ones we do! setOperationAction(ISD::ConstantVec, MVT::v4f32, Expand); From evan.cheng at apple.com Tue Feb 28 19:11:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 28 Feb 2006 19:11:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200603010111.TAA13895@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.97 -> 1.98 --- Log message: Vector op lowering. --- Diffs of the changes: (+19 -6) X86ISelLowering.cpp | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.97 llvm/lib/Target/X86/X86ISelLowering.cpp:1.98 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.97 Sat Feb 25 03:55:19 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Feb 28 19:11:20 2006 @@ -238,13 +238,22 @@ addLegalFPImmediate(-1.0); // FLD1/FCHS } + // First set operation action for all vector types to expand. Then we + // will selectively turn on ones that can be effectively codegen'd. + for (unsigned VT = (unsigned)MVT::Vector + 1; + VT != (unsigned)MVT::LAST_VALUETYPE; VT++) { + setOperationAction(ISD::ADD , (MVT::ValueType)VT, Expand); + setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand); + setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand); + setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand); + } + if (TM.getSubtarget().hasMMX()) { addRegisterClass(MVT::v8i8, X86::VR64RegisterClass); addRegisterClass(MVT::v4i16, X86::VR64RegisterClass); addRegisterClass(MVT::v2i32, X86::VR64RegisterClass); - // FIXME: We don't support any ConstantVec's yet. We should custom expand - // the ones we do! + // FIXME: add MMX packed arithmetics setOperationAction(ISD::ConstantVec, MVT::v8i8, Expand); setOperationAction(ISD::ConstantVec, MVT::v4i16, Expand); setOperationAction(ISD::ConstantVec, MVT::v2i32, Expand); @@ -253,8 +262,10 @@ if (TM.getSubtarget().hasSSE1()) { addRegisterClass(MVT::v4f32, X86::VR128RegisterClass); - // FIXME: We don't support any ConstantVec's yet. We should custom expand - // the ones we do! + setOperationAction(ISD::ADD , MVT::v4f32, Legal); + setOperationAction(ISD::SUB , MVT::v4f32, Legal); + setOperationAction(ISD::MUL , MVT::v4f32, Legal); + setOperationAction(ISD::LOAD , MVT::v4f32, Legal); setOperationAction(ISD::ConstantVec, MVT::v4f32, Expand); } @@ -266,8 +277,10 @@ addRegisterClass(MVT::v2i64, X86::VR128RegisterClass); - // FIXME: We don't support any ConstantVec's yet. We should custom expand - // the ones we do! + setOperationAction(ISD::ADD , MVT::v2f64, Legal); + setOperationAction(ISD::SUB , MVT::v2f64, Legal); + setOperationAction(ISD::MUL , MVT::v2f64, Legal); + setOperationAction(ISD::LOAD , MVT::v2f64, Legal); setOperationAction(ISD::ConstantVec, MVT::v2f64, Expand); setOperationAction(ISD::ConstantVec, MVT::v16i8, Expand); setOperationAction(ISD::ConstantVec, MVT::v8i16, Expand); From lattner at cs.uiuc.edu Tue Feb 28 21:43:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 21:43:50 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/mul-shift-reassoc.ll Message-ID: <200603010343.VAA14688@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: mul-shift-reassoc.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+12 -0) mul-shift-reassoc.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/CodeGen/X86/mul-shift-reassoc.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/mul-shift-reassoc.ll:1.1 *** /dev/null Tue Feb 28 21:43:48 2006 --- llvm/test/Regression/CodeGen/X86/mul-shift-reassoc.ll Tue Feb 28 21:43:38 2006 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=x86 | grep lea + ; RUN: llvm-as < %s | llc -march=x86 | not grep add + + int %test(int %X, int %Y) { + ; Push the shl through the mul to allow an LEA to be formed, instead + ; of using a shift and add separately. + %tmp.2 = shl int %X, ubyte 1 + %tmp.3 = mul int %tmp.2, %Y + %tmp.5 = add int %tmp.3, %Y + ret int %tmp.5 + } + From lattner at cs.uiuc.edu Tue Feb 28 21:44:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 21:44:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200603010344.VAA14729@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.114 -> 1.115 --- Log message: Pull shifts by a constant through multiplies (a form of reassociation), implementing Regression/CodeGen/X86/mul-shift-reassoc.ll --- Diffs of the changes: (+27 -0) DAGCombiner.cpp | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.114 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.115 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.114 Tue Feb 28 19:09:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 21:44:24 2006 @@ -726,6 +726,33 @@ DAG.getConstant(Log2_64(-N1C->getSignExtended()), TLI.getShiftAmountTy()))); } + + // (mul (shl X, c1), c2) -> (mul X, c2 << c1) + if (N1C && N0.getOpcode() == ISD::SHL && + isa(N0.getOperand(1))) { + SDOperand C3 = DAG.getNode(ISD::SHL, VT, N1, N0.getOperand(1)); + return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), C3); + } + + // Change (mul (shl X, C), Y) -> (shl (mul X, Y), C) when the shift has one + // use. + { + SDOperand Sh(0,0), Y(0,0); + // Check for both (mul (shl X, C), Y) and (mul Y, (shl X, C)). + if (N0.getOpcode() == ISD::SHL && isa(N0.getOperand(1)) && + N0.Val->hasOneUse()) { + Sh = N0; Y = N1; + } else if (N1.getOpcode() == ISD::SHL && + isa(N1.getOperand(1)) && N1.Val->hasOneUse()) { + Sh = N1; Y = N0; + } + if (Sh.Val) { + SDOperand Mul = DAG.getNode(ISD::MUL, VT, Sh.getOperand(0), Y); + return DAG.getNode(ISD::SHL, VT, Mul, Sh.getOperand(1)); + } + } + + // reassociate mul SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1); if (RMUL.Val != 0) From lattner at cs.uiuc.edu Tue Feb 28 22:03:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 22:03:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200603010403.WAA14913@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.115 -> 1.116 --- Log message: Add a new AddToWorkList method, start using it --- Diffs of the changes: (+63 -57) DAGCombiner.cpp | 120 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 63 insertions(+), 57 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.115 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.116 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.115 Tue Feb 28 21:44:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 22:03:14 2006 @@ -62,11 +62,16 @@ } /// removeFromWorkList - remove all instances of N from the worklist. + /// void removeFromWorkList(SDNode *N) { WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), N), WorkList.end()); } + void AddToWorkList(SDNode *N) { + WorkList.push_back(N); + } + SDOperand CombineTo(SDNode *N, const std::vector &To) { ++NodesCombined; DEBUG(std::cerr << "\nReplacing "; N->dump(); @@ -452,11 +457,11 @@ if (N0.getOpcode() == Opc && isa(N0.getOperand(1))) { if (isa(N1)) { SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1); - WorkList.push_back(OpNode.Val); + AddToWorkList(OpNode.Val); return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0)); } else if (N0.hasOneUse()) { SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1); - WorkList.push_back(OpNode.Val); + AddToWorkList(OpNode.Val); return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1)); } } @@ -465,11 +470,11 @@ if (N1.getOpcode() == Opc && isa(N1.getOperand(1))) { if (isa(N0)) { SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0); - WorkList.push_back(OpNode.Val); + AddToWorkList(OpNode.Val); return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0)); } else if (N1.hasOneUse()) { SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0); - WorkList.push_back(OpNode.Val); + AddToWorkList(OpNode.Val); return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1)); } } @@ -731,6 +736,7 @@ if (N1C && N0.getOpcode() == ISD::SHL && isa(N0.getOperand(1))) { SDOperand C3 = DAG.getNode(ISD::SHL, VT, N1, N0.getOperand(1)); + AddToWorkList(C3.Val); return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), C3); } @@ -797,21 +803,21 @@ SDOperand SGN = DAG.getNode(ISD::SRA, VT, N0, DAG.getConstant(MVT::getSizeInBits(VT)-1, TLI.getShiftAmountTy())); - WorkList.push_back(SGN.Val); + AddToWorkList(SGN.Val); // Add (N0 < 0) ? abs2 - 1 : 0; SDOperand SRL = DAG.getNode(ISD::SRL, VT, SGN, DAG.getConstant(MVT::getSizeInBits(VT)-lg2, TLI.getShiftAmountTy())); SDOperand ADD = DAG.getNode(ISD::ADD, VT, N0, SRL); - WorkList.push_back(SRL.Val); - WorkList.push_back(ADD.Val); // Divide by pow2 + AddToWorkList(SRL.Val); + AddToWorkList(ADD.Val); // Divide by pow2 SDOperand SRA = DAG.getNode(ISD::SRA, VT, ADD, DAG.getConstant(lg2, TLI.getShiftAmountTy())); // If we're dividing by a positive value, we're done. Otherwise, we must // negate the result. if (pow2 > 0) return SRA; - WorkList.push_back(SRA.Val); + AddToWorkList(SRA.Val); return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), SRA); } // if integer divide is expensive and we satisfy the requirements, emit an @@ -847,7 +853,7 @@ SDOperand Add = DAG.getNode(ISD::ADD, ADDVT, N1.getOperand(1), DAG.getConstant(Log2_64(SHC->getValue()), ADDVT)); - WorkList.push_back(Add.Val); + AddToWorkList(Add.Val); return DAG.getNode(ISD::SRL, VT, N0, Add); } } @@ -897,7 +903,7 @@ if (ConstantSDNode *SHC = dyn_cast(N1.getOperand(0))) { if (isPowerOf2_64(SHC->getValue())) { SDOperand Add = DAG.getNode(ISD::ADD, VT, N1,DAG.getConstant(~0ULL,VT)); - WorkList.push_back(Add.Val); + AddToWorkList(Add.Val); return DAG.getNode(ISD::AND, VT, N0, Add); } } @@ -988,19 +994,19 @@ // fold (X == 0) & (Y == 0) -> (X|Y == 0) if (cast(LR)->getValue() == 0 && Op1 == ISD::SETEQ) { SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); - WorkList.push_back(ORNode.Val); + AddToWorkList(ORNode.Val); return DAG.getSetCC(VT, ORNode, LR, Op1); } // fold (X == -1) & (Y == -1) -> (X&Y == -1) if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) { SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); - WorkList.push_back(ANDNode.Val); + AddToWorkList(ANDNode.Val); return DAG.getSetCC(VT, ANDNode, LR, Op1); } // fold (X > -1) & (Y > -1) -> (X|Y > -1) if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETGT) { SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); - WorkList.push_back(ORNode.Val); + AddToWorkList(ORNode.Val); return DAG.getSetCC(VT, ORNode, LR, Op1); } } @@ -1022,7 +1028,7 @@ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(), N0.getOperand(0), N1.getOperand(0)); - WorkList.push_back(ANDNode.Val); + AddToWorkList(ANDNode.Val); return DAG.getNode(ISD::ZERO_EXTEND, VT, ANDNode); } // fold (and (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (and x, y)) @@ -1032,7 +1038,7 @@ N0.getOperand(1) == N1.getOperand(1)) { SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(), N0.getOperand(0), N1.getOperand(0)); - WorkList.push_back(ANDNode.Val); + AddToWorkList(ANDNode.Val); return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) @@ -1049,7 +1055,7 @@ SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); - WorkList.push_back(N); + AddToWorkList(N); CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); return SDOperand(); } @@ -1064,7 +1070,7 @@ SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), EVT); - WorkList.push_back(N); + AddToWorkList(N); CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); return SDOperand(); } @@ -1099,11 +1105,11 @@ if (!TLI.isLittleEndian()) NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr, DAG.getConstant(PtrOff, PtrType)); - WorkList.push_back(NewPtr.Val); + AddToWorkList(NewPtr.Val); SDOperand Load = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), NewPtr, N0.getOperand(2), EVT); - WorkList.push_back(N); + AddToWorkList(N); CombineTo(N0.Val, Load, Load.getValue(1)); return SDOperand(); } @@ -1161,7 +1167,7 @@ if (cast(LR)->getValue() == 0 && (Op1 == ISD::SETNE || Op1 == ISD::SETLT)) { SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); - WorkList.push_back(ORNode.Val); + AddToWorkList(ORNode.Val); return DAG.getSetCC(VT, ORNode, LR, Op1); } // fold (X != -1) | (Y != -1) -> (X&Y != -1) @@ -1169,7 +1175,7 @@ if (cast(LR)->isAllOnesValue() && (Op1 == ISD::SETNE || Op1 == ISD::SETGT)) { SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); - WorkList.push_back(ANDNode.Val); + AddToWorkList(ANDNode.Val); return DAG.getSetCC(VT, ANDNode, LR, Op1); } } @@ -1191,7 +1197,7 @@ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(), N0.getOperand(0), N1.getOperand(0)); - WorkList.push_back(ORNode.Val); + AddToWorkList(ORNode.Val); return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode); } // fold (or (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (or x, y)) @@ -1201,7 +1207,7 @@ N0.getOperand(1) == N1.getOperand(1)) { SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(), N0.getOperand(0), N1.getOperand(0)); - WorkList.push_back(ORNode.Val); + AddToWorkList(ORNode.Val); return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1)); } // canonicalize shl to left side in a shl/srl pair, to match rotate @@ -1284,7 +1290,7 @@ unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND; LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS - WorkList.push_back(LHS.Val); WorkList.push_back(RHS.Val); + AddToWorkList(LHS.Val); AddToWorkList(RHS.Val); return DAG.getNode(NewOpcode, VT, LHS, RHS); } } @@ -1296,7 +1302,7 @@ unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND; LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS - WorkList.push_back(LHS.Val); WorkList.push_back(RHS.Val); + AddToWorkList(LHS.Val); AddToWorkList(RHS.Val); return DAG.getNode(NewOpcode, VT, LHS, RHS); } } @@ -1320,7 +1326,7 @@ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(), N0.getOperand(0), N1.getOperand(0)); - WorkList.push_back(XORNode.Val); + AddToWorkList(XORNode.Val); return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode); } // fold (xor (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (xor x, y)) @@ -1330,7 +1336,7 @@ N0.getOperand(1) == N1.getOperand(1)) { SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(), N0.getOperand(0), N1.getOperand(0)); - WorkList.push_back(XORNode.Val); + AddToWorkList(XORNode.Val); return DAG.getNode(N0.getOpcode(), VT, XORNode, N0.getOperand(1)); } return SDOperand(); @@ -1542,13 +1548,13 @@ // FIXME: this should check for C type == X type, not i1? if (MVT::i1 == VT && N1C && N1C->isNullValue()) { SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); - WorkList.push_back(XORNode.Val); + AddToWorkList(XORNode.Val); return DAG.getNode(ISD::AND, VT, XORNode, N2); } // fold select C, X, 1 -> ~C | X if (MVT::i1 == VT && N2C && N2C->getValue() == 1) { SDOperand XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); - WorkList.push_back(XORNode.Val); + AddToWorkList(XORNode.Val); return DAG.getNode(ISD::OR, VT, XORNode, N1); } // fold select C, X, 0 -> C & X @@ -1810,9 +1816,9 @@ SDOperand NewPtr = TLI.isLittleEndian() ? N0.getOperand(1) : DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), DAG.getConstant(PtrOff, PtrType)); - WorkList.push_back(NewPtr.Val); + AddToWorkList(NewPtr.Val); SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), NewPtr,N0.getOperand(2)); - WorkList.push_back(N); + AddToWorkList(N); CombineTo(N0.Val, Load, Load.getValue(1)); return SDOperand(); } @@ -1838,7 +1844,7 @@ if (0 && N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) { SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2)); - WorkList.push_back(N); + AddToWorkList(N); CombineTo(N0.Val, DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load), Load.getValue(1)); return Load; @@ -2221,7 +2227,7 @@ SDOperand SETCC = DAG.getNode(ISD::SETCC, N0.getValueType(), SCC.getOperand(0), SCC.getOperand(1), SCC.getOperand(4)); - WorkList.push_back(SETCC.Val); + AddToWorkList(SETCC.Val); return DAG.getNode(ISD::SELECT, SCC.getValueType(), SCC.getOperand(2), SCC.getOperand(3), SETCC); } @@ -2350,20 +2356,20 @@ ShCtV = MVT::getSizeInBits(XType)-ShCtV-1; SDOperand ShCt = DAG.getConstant(ShCtV, TLI.getShiftAmountTy()); SDOperand Shift = DAG.getNode(ISD::SRL, XType, N0, ShCt); - WorkList.push_back(Shift.Val); + AddToWorkList(Shift.Val); if (XType > AType) { Shift = DAG.getNode(ISD::TRUNCATE, AType, Shift); - WorkList.push_back(Shift.Val); + AddToWorkList(Shift.Val); } return DAG.getNode(ISD::AND, AType, Shift, N2); } SDOperand Shift = DAG.getNode(ISD::SRA, XType, N0, DAG.getConstant(MVT::getSizeInBits(XType)-1, TLI.getShiftAmountTy())); - WorkList.push_back(Shift.Val); + AddToWorkList(Shift.Val); if (XType > AType) { Shift = DAG.getNode(ISD::TRUNCATE, AType, Shift); - WorkList.push_back(Shift.Val); + AddToWorkList(Shift.Val); } return DAG.getNode(ISD::AND, AType, Shift, N2); } @@ -2384,8 +2390,8 @@ SCC = DAG.getSetCC(MVT::i1, N0, N1, CC); Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getValueType(), SCC); } - WorkList.push_back(SCC.Val); - WorkList.push_back(Temp.Val); + AddToWorkList(SCC.Val); + AddToWorkList(Temp.Val); // shl setcc result by log2 n2c return DAG.getNode(ISD::SHL, N2.getValueType(), Temp, DAG.getConstant(Log2_64(N2C->getValue()), @@ -2443,8 +2449,8 @@ DAG.getConstant(MVT::getSizeInBits(XType)-1, TLI.getShiftAmountTy())); SDOperand Add = DAG.getNode(ISD::ADD, XType, N0, Shift); - WorkList.push_back(Shift.Val); - WorkList.push_back(Add.Val); + AddToWorkList(Shift.Val); + AddToWorkList(Add.Val); return DAG.getNode(ISD::XOR, XType, Add, Shift); } } @@ -2556,7 +2562,7 @@ ZextOp = DAG.getNode(ISD::AND, Op0Ty, N0.getOperand(0), DAG.getConstant(Imm, Op0Ty)); } - WorkList.push_back(ZextOp.Val); + AddToWorkList(ZextOp.Val); // Otherwise, make this a use of a zext. return DAG.getSetCC(VT, ZextOp, DAG.getConstant(C1 & (~0ULL>>(64-ExtSrcTyBits)), @@ -2771,7 +2777,7 @@ SDOperand SH = DAG.getNode(ISD::SHL, N1.getValueType(), N1, DAG.getConstant(1,TLI.getShiftAmountTy())); - WorkList.push_back(SH.Val); + AddToWorkList(SH.Val); return DAG.getSetCC(VT, N0.getOperand(0), SH, Cond); } } @@ -2792,7 +2798,7 @@ // X == (Z-X) --> X<<1 == Z SDOperand SH = DAG.getNode(ISD::SHL, N1.getValueType(), N0, DAG.getConstant(1,TLI.getShiftAmountTy())); - WorkList.push_back(SH.Val); + AddToWorkList(SH.Val); return DAG.getSetCC(VT, SH, N1.getOperand(0), Cond); } } @@ -2807,7 +2813,7 @@ case ISD::SETEQ: // X == Y -> (X^Y)^1 Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); N0 = DAG.getNode(ISD::XOR, MVT::i1, Temp, DAG.getConstant(1, MVT::i1)); - WorkList.push_back(Temp.Val); + AddToWorkList(Temp.Val); break; case ISD::SETNE: // X != Y --> (X^Y) N0 = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); @@ -2816,19 +2822,19 @@ case ISD::SETULT: // X X == 0 & Y == 1 --> X^1 & Y Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1)); N0 = DAG.getNode(ISD::AND, MVT::i1, N1, Temp); - WorkList.push_back(Temp.Val); + AddToWorkList(Temp.Val); break; case ISD::SETLT: // X X == 1 & Y == 0 --> Y^1 & X case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> Y^1 & X Temp = DAG.getNode(ISD::XOR, MVT::i1, N1, DAG.getConstant(1, MVT::i1)); N0 = DAG.getNode(ISD::AND, MVT::i1, N0, Temp); - WorkList.push_back(Temp.Val); + AddToWorkList(Temp.Val); break; case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> X^1 | Y case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> X^1 | Y Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1)); N0 = DAG.getNode(ISD::OR, MVT::i1, N1, Temp); - WorkList.push_back(Temp.Val); + AddToWorkList(Temp.Val); break; case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> Y^1 | X case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> Y^1 | X @@ -2837,7 +2843,7 @@ break; } if (VT != MVT::i1) { - WorkList.push_back(N0.Val); + AddToWorkList(N0.Val); // FIXME: If running after legalize, we probably can't do this. N0 = DAG.getNode(ISD::ZERO_EXTEND, VT, N0); } @@ -2870,24 +2876,24 @@ // If d > 0 and m < 0, add the numerator if (d > 0 && magics.m < 0) { Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0)); - WorkList.push_back(Q.Val); + AddToWorkList(Q.Val); } // If d < 0 and m > 0, subtract the numerator. if (d < 0 && magics.m > 0) { Q = DAG.getNode(ISD::SUB, VT, Q, N->getOperand(0)); - WorkList.push_back(Q.Val); + AddToWorkList(Q.Val); } // Shift right algebraic if shift value is nonzero if (magics.s > 0) { Q = DAG.getNode(ISD::SRA, VT, Q, DAG.getConstant(magics.s, TLI.getShiftAmountTy())); - WorkList.push_back(Q.Val); + AddToWorkList(Q.Val); } // Extract the sign bit and add it to the quotient SDOperand T = DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(MVT::getSizeInBits(VT)-1, TLI.getShiftAmountTy())); - WorkList.push_back(T.Val); + AddToWorkList(T.Val); return DAG.getNode(ISD::ADD, VT, Q, T); } @@ -2910,19 +2916,19 @@ // Multiply the numerator (operand 0) by the magic value SDOperand Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), DAG.getConstant(magics.m, VT)); - WorkList.push_back(Q.Val); + AddToWorkList(Q.Val); if (magics.a == 0) { return DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(magics.s, TLI.getShiftAmountTy())); } else { SDOperand NPQ = DAG.getNode(ISD::SUB, VT, N->getOperand(0), Q); - WorkList.push_back(NPQ.Val); + AddToWorkList(NPQ.Val); NPQ = DAG.getNode(ISD::SRL, VT, NPQ, DAG.getConstant(1, TLI.getShiftAmountTy())); - WorkList.push_back(NPQ.Val); + AddToWorkList(NPQ.Val); NPQ = DAG.getNode(ISD::ADD, VT, NPQ, Q); - WorkList.push_back(NPQ.Val); + AddToWorkList(NPQ.Val); return DAG.getNode(ISD::SRL, VT, NPQ, DAG.getConstant(magics.s-1, TLI.getShiftAmountTy())); } From lattner at cs.uiuc.edu Tue Feb 28 22:52:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 22:52:42 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200603010452.WAA15106@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.56 -> 1.57 --- Log message: Add interfaces for targets to provide target-specific dag combiner optimizations. --- Diffs of the changes: (+59 -9) TargetLowering.h | 68 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 59 insertions(+), 9 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.56 llvm/include/llvm/Target/TargetLowering.h:1.57 --- llvm/include/llvm/Target/TargetLowering.h:1.56 Tue Feb 28 18:58:54 2006 +++ llvm/include/llvm/Target/TargetLowering.h Tue Feb 28 22:52:29 2006 @@ -239,6 +239,12 @@ unsigned getNumElements(MVT::ValueType VT) const { return NumElementsForVT[VT]; } + + /// hasTargetDAGCombine - If true, the target has custom DAG combine + /// transformations that it can perform for the specified node. + bool hasTargetDAGCombine(ISD::NodeType NT) const { + return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7)); + } /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memset. The value is set by the target at the @@ -334,6 +340,47 @@ uint64_t &KnownZero, uint64_t &KnownOne, TargetLoweringOpt &TLO, unsigned Depth = 0) const; + /// computeMaskedBitsForTargetNode - Determine which of the bits specified in + /// Mask are known to be either zero or one and return them in the + /// KnownZero/KnownOne bitsets. + virtual void computeMaskedBitsForTargetNode(const SDOperand Op, + uint64_t Mask, + uint64_t &KnownZero, + uint64_t &KnownOne, + unsigned Depth = 0) const; + + struct DAGCombinerInfo { + void *DC; // The DAG Combiner object. + bool BeforeLegalize; + public: + SelectionDAG &DAG; + + DAGCombinerInfo(SelectionDAG &dag, bool bl, void *dc) + : DC(dc), BeforeLegalize(bl), DAG(dag) {} + + bool isBeforeLegalize() const { return BeforeLegalize; } + + void AddToWorklist(SDNode *N); + SDOperand CombineTo(SDNode *N, const std::vector &To); + SDOperand CombineTo(SDNode *N, SDOperand Res); + SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1); + }; + + /// PerformDAGCombine - This method will be invoked for all target nodes and + /// for any target-independent nodes that the target has registered with + /// invoke it for. + /// + /// The semantics are as follows: + /// Return Value: + /// SDOperand.Val == 0 - No change was made + /// SDOperand.Val == N - N was replaced, is dead, and is already handled. + /// otherwise - N should be replaced by the returned Operand. + /// + /// In addition, methods provided by DAGCombinerInfo may be used to perform + /// more complex transformations. + /// + virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by // the derived class constructor to configure this object for the target. @@ -421,6 +468,13 @@ LegalFPImmediates.push_back(Imm); } + /// setTargetDAGCombine - Targets should invoke this method for each target + /// independent node that they want to provide a custom DAG combiner for by + /// implementing the PerformDAGCombine virtual method. + void setTargetDAGCombine(ISD::NodeType NT) { + TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7); + } + public: //===--------------------------------------------------------------------===// @@ -467,15 +521,6 @@ /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; - /// computeMaskedBitsForTargetNode - Determine which of the bits specified in - /// Mask are known to be either zero or one and return them in the - /// KnownZero/KnownOne bitsets. - virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - uint64_t Mask, - uint64_t &KnownZero, - uint64_t &KnownOne, - unsigned Depth = 0) const; - //===--------------------------------------------------------------------===// // Inline Asm Support hooks // @@ -606,6 +651,11 @@ std::vector > AvailableRegClasses; + /// TargetDAGCombineArray - Targets can specify ISD nodes that they would + /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(), + /// which sets a bit in this array. + unsigned char TargetDAGCombineArray[128/(sizeof(unsigned char)*8)]; + protected: /// When lowering %llvm.memset this field specifies the maximum number of /// store operations that may be substituted for the call to memset. Targets From lattner at cs.uiuc.edu Tue Feb 28 22:53:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 22:53:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200603010453.WAA15162@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.41 -> 1.42 --- Log message: Add interfaces for targets to provide target-specific dag combiner optimizations. --- Diffs of the changes: (+8 -0) TargetLowering.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.41 llvm/lib/Target/TargetLowering.cpp:1.42 --- llvm/lib/Target/TargetLowering.cpp:1.41 Sun Feb 26 19:00:42 2006 +++ llvm/lib/Target/TargetLowering.cpp Tue Feb 28 22:52:55 2006 @@ -30,6 +30,8 @@ ShiftAmountTy = SetCCResultTy = PointerTy = getValueType(TD.getIntPtrType()); ShiftAmtHandling = Undefined; memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); + memset(TargetDAGCombineArray, 0, + sizeof(TargetDAGCombineArray)/sizeof(TargetDAGCombineArray[0])); maxStoresPerMemset = maxStoresPerMemcpy = maxStoresPerMemmove = 8; allowUnalignedMemoryAccesses = false; UseUnderscoreSetJmpLongJmp = false; @@ -916,6 +918,12 @@ KnownOne = 0; } +SDOperand TargetLowering:: +PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { + // Default implementation: no optimization. + return SDOperand(); +} + //===----------------------------------------------------------------------===// // Inline Assembler Implementation Methods //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Tue Feb 28 22:53:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 22:53:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200603010453.WAA15219@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.116 -> 1.117 --- Log message: Add support for target-specific dag combines --- Diffs of the changes: (+58 -13) DAGCombiner.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 58 insertions(+), 13 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.116 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.117 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.116 Tue Feb 28 22:03:14 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Feb 28 22:53:38 2006 @@ -68,6 +68,7 @@ WorkList.end()); } + public: void AddToWorkList(SDNode *N) { WorkList.push_back(N); } @@ -97,6 +98,20 @@ return SDOperand(N, 0); } + SDOperand CombineTo(SDNode *N, SDOperand Res) { + std::vector To; + To.push_back(Res); + return CombineTo(N, To); + } + + SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1) { + std::vector To; + To.push_back(Res0); + To.push_back(Res1); + return CombineTo(N, To); + } + private: + /// SimplifyDemandedBits - Check the specified integer node value to see if /// it can be simplified or if things is uses can be simplified by bit /// propagation. If so, return true. @@ -137,19 +152,6 @@ return true; } - SDOperand CombineTo(SDNode *N, SDOperand Res) { - std::vector To; - To.push_back(Res); - return CombineTo(N, To); - } - - SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1) { - std::vector To; - To.push_back(Res0); - To.push_back(Res1); - return CombineTo(N, To); - } - /// visit - call the node-specific routine that knows how to fold each /// particular type of node. SDOperand visit(SDNode *N); @@ -229,6 +231,36 @@ }; } +//===----------------------------------------------------------------------===// +// TargetLowering::DAGCombinerInfo implementation +//===----------------------------------------------------------------------===// + +void TargetLowering::DAGCombinerInfo::AddToWorklist(SDNode *N) { + ((DAGCombiner*)DC)->AddToWorkList(N); +} + +SDOperand TargetLowering::DAGCombinerInfo:: +CombineTo(SDNode *N, const std::vector &To) { + return ((DAGCombiner*)DC)->CombineTo(N, To); +} + +SDOperand TargetLowering::DAGCombinerInfo:: +CombineTo(SDNode *N, SDOperand Res) { + return ((DAGCombiner*)DC)->CombineTo(N, Res); +} + + +SDOperand TargetLowering::DAGCombinerInfo:: +CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1) { + return ((DAGCombiner*)DC)->CombineTo(N, Res0, Res1); +} + + + + +//===----------------------------------------------------------------------===// + + struct ms { int64_t m; // magic number int64_t s; // shift amount @@ -495,6 +527,11 @@ // changes of the root. HandleSDNode Dummy(DAG.getRoot()); + + /// DagCombineInfo - Expose the DAG combiner to the target combiner impls. + TargetLowering::DAGCombinerInfo + DagCombineInfo(DAG, !RunningAfterLegalize, this); + // while the worklist isn't empty, inspect the node on the end of it and // try and combine it. while (!WorkList.empty()) { @@ -514,6 +551,14 @@ } SDOperand RV = visit(N); + + // If nothing happened, try a target-specific DAG combine. + if (RV.Val == 0) { + if (N->getOpcode() >= ISD::BUILTIN_OP_END || + TLI.hasTargetDAGCombine((ISD::NodeType)N->getOpcode())) + RV = TLI.PerformDAGCombine(N, DagCombineInfo); + } + if (RV.Val) { ++NodesCombined; // If we get back the same node we passed in, rather than a new node or From lattner at cs.uiuc.edu Tue Feb 28 22:56:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 22:56:44 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/fp-int-fp.ll Message-ID: <200603010456.WAA15310@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: fp-int-fp.ll added (r1.1) --- Log message: new testcase. There should be no accesses to the stack for these functions. --- Diffs of the changes: (+27 -0) fp-int-fp.ll | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/fp-int-fp.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fp-int-fp.ll:1.1 *** /dev/null Tue Feb 28 22:56:43 2006 --- llvm/test/Regression/CodeGen/PowerPC/fp-int-fp.ll Tue Feb 28 22:56:33 2006 *************** *** 0 **** --- 1,27 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 && + ; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5 | not grep r1 + + double %test1(double %X) { + %Y = cast double %X to long + %Z = cast long %Y to double + ret double %Z + } + + float %test2(double %X) { + %Y = cast double %X to long + %Z = cast long %Y to float + ret float %Z + } + + double %test3(float %X) { + %Y = cast float %X to long + %Z = cast long %Y to double + ret double %Z + } + + float %test4(float %X) { + %Y = cast float %X to long + %Z = cast long %Y to float + ret float %Z + } + From lattner at cs.uiuc.edu Tue Feb 28 22:57:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 22:57:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h README.txt Message-ID: <200603010457.WAA15348@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.92 -> 1.93 PPCISelLowering.h updated: 1.23 -> 1.24 README.txt updated: 1.65 -> 1.66 --- Log message: Use a target-specific dag-combine to implement CodeGen/PowerPC/fp-int-fp.ll. --- Diffs of the changes: (+42 -25) PPCISelLowering.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ PPCISelLowering.h | 2 ++ README.txt | 25 ------------------------- 3 files changed, 42 insertions(+), 25 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.92 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.93 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.92 Tue Feb 28 19:11:20 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Feb 28 22:57:39 2006 @@ -185,6 +185,9 @@ setSetCCResultContents(ZeroOrOneSetCCResult); setStackPointerRegisterToSaveRestore(PPC::R1); + // We have target-specific dag combine patterns for the following nodes: + setTargetDAGCombine(ISD::SINT_TO_FP); + computeRegisterProperties(); } @@ -997,6 +1000,43 @@ return BB; } +SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N, + DAGCombinerInfo &DCI) const { + TargetMachine &TM = getTargetMachine(); + SelectionDAG &DAG = DCI.DAG; + switch (N->getOpcode()) { + default: break; + case ISD::SINT_TO_FP: + if (TM.getSubtarget().is64Bit()) { + // Turn (sint_to_fp (fp_to_sint X)) -> fctidz/fcfid without load/stores. + // We allow the src/dst to be either f32/f64, but force the intermediate + // type to be i64. + if (N->getOperand(0).getOpcode() == ISD::FP_TO_SINT && + N->getOperand(0).getValueType() == MVT::i64) { + + SDOperand Val = N->getOperand(0).getOperand(0); + if (Val.getValueType() == MVT::f32) { + Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); + DCI.AddToWorklist(Val.Val); + } + + Val = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Val); + DCI.AddToWorklist(Val.Val); + Val = DAG.getNode(PPCISD::FCFID, MVT::f64, Val); + DCI.AddToWorklist(Val.Val); + if (N->getValueType(0) == MVT::f32) { + Val = DAG.getNode(ISD::FP_ROUND, MVT::f32, Val); + DCI.AddToWorklist(Val.Val); + } + return Val; + } + } + break; + } + + return SDOperand(); +} + /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. PPCTargetLowering::ConstraintType Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.23 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.24 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.23 Tue Feb 21 18:56:38 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Tue Feb 28 22:57:39 2006 @@ -81,6 +81,8 @@ /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + /// LowerArguments - This hook must be implemented to indicate how we should /// lower the arguments for the specified function, into the specified DAG. virtual std::vector Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.65 llvm/lib/Target/PowerPC/README.txt:1.66 --- llvm/lib/Target/PowerPC/README.txt:1.65 Tue Feb 28 00:36:04 2006 +++ llvm/lib/Target/PowerPC/README.txt Tue Feb 28 22:57:39 2006 @@ -328,31 +328,6 @@ Compile this: -double %test(double %X) { - %Y = cast double %X to long - %Z = cast long %Y to double - ret double %Z -} - -to this: - -_test: - fctidz f0, f1 - stfd f0, -8(r1) - lwz r2, -4(r1) - lwz r3, -8(r1) - stw r2, -12(r1) - stw r3, -16(r1) - lfd f0, -16(r1) - fcfid f1, f0 - blr - -without the lwz/stw's. - -===-------------------------------------------------------------------------=== - -Compile this: - int foo(int a) { int b = (a < 8); if (b) { From lattner at cs.uiuc.edu Tue Feb 28 23:49:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 23:49:18 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/stfiwx.ll Message-ID: <200603010549.XAA15743@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: stfiwx.ll added (r1.1) --- Log message: new testcase. These functions shouldn't touch the stack if stfiwx use is enabled. --- Diffs of the changes: (+21 -0) stfiwx.ll | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/stfiwx.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/stfiwx.ll:1.1 *** /dev/null Tue Feb 28 23:49:15 2006 --- llvm/test/Regression/CodeGen/PowerPC/stfiwx.ll Tue Feb 28 23:49:05 2006 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=stfiwx | grep stfiwx && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=stfiwx | not grep r1 && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=-stfiwx | not grep stfiwx && + ; RUN: llvm-as < %s | llc -march=ppc32 -mattr=-stfiwx | grep r1 + + void %test(float %a, int* %b) { + %tmp.2 = cast float %a to int + store int %tmp.2, int* %b + ret void + } + + void %test2(float %a, int* %b, int %i) { + %tmp.2 = getelementptr int* %b, int 1 + %tmp.5 = getelementptr int* %b, int %i + %tmp.7 = cast float %a to int + store int %tmp.7, int* %tmp.5 + store int %tmp.7, int* %tmp.2 + store int %tmp.7, int* %b + ret void + } + From lattner at cs.uiuc.edu Tue Feb 28 23:51:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 28 Feb 2006 23:51:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h PPCInstrInfo.td PPCSubtarget.cpp README.txt Message-ID: <200603010551.XAA15800@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.93 -> 1.94 PPCISelLowering.h updated: 1.24 -> 1.25 PPCInstrInfo.td updated: 1.177 -> 1.178 PPCSubtarget.cpp updated: 1.18 -> 1.19 README.txt updated: 1.66 -> 1.67 --- Log message: Compile this: void foo(float a, int *b) { *b = a; } to this: _foo: fctiwz f0, f1 stfiwx f0, 0, r4 blr instead of this: _foo: fctiwz f0, f1 stfd f0, -8(r1) lwz r2, -4(r1) stw r2, 0(r4) blr This implements CodeGen/PowerPC/stfiwx.ll, and also incidentally does the right thing for GCC bugzilla 26505. --- Diffs of the changes: (+42 -13) PPCISelLowering.cpp | 21 +++++++++++++++++++++ PPCISelLowering.h | 5 +++++ PPCInstrInfo.td | 22 +++++++++++++++------- PPCSubtarget.cpp | 1 + README.txt | 6 ------ 5 files changed, 42 insertions(+), 13 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.93 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.94 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.93 Tue Feb 28 22:57:39 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Feb 28 23:50:56 2006 @@ -187,6 +187,7 @@ // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::SINT_TO_FP); + setTargetDAGCombine(ISD::STORE); computeRegisterProperties(); } @@ -198,6 +199,7 @@ case PPCISD::FCFID: return "PPCISD::FCFID"; case PPCISD::FCTIDZ: return "PPCISD::FCTIDZ"; case PPCISD::FCTIWZ: return "PPCISD::FCTIWZ"; + case PPCISD::STFIWX: return "PPCISD::STFIWX"; case PPCISD::VMADDFP: return "PPCISD::VMADDFP"; case PPCISD::VNMSUBFP: return "PPCISD::VNMSUBFP"; case PPCISD::Hi: return "PPCISD::Hi"; @@ -1032,6 +1034,25 @@ } } break; + case ISD::STORE: + // Turn STORE (FP_TO_SINT F) -> STFIWX(FCTIWZ(F)). + if (TM.getSubtarget().hasSTFIWX() && + N->getOperand(1).getOpcode() == ISD::FP_TO_SINT && + N->getOperand(1).getValueType() == MVT::i32) { + SDOperand Val = N->getOperand(1).getOperand(0); + if (Val.getValueType() == MVT::f32) { + Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); + DCI.AddToWorklist(Val.Val); + } + Val = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Val); + DCI.AddToWorklist(Val.Val); + + Val = DAG.getNode(PPCISD::STFIWX, MVT::Other, N->getOperand(0), Val, + N->getOperand(2), N->getOperand(3)); + DCI.AddToWorklist(Val.Val); + return Val; + } + break; } return SDOperand(); Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.24 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.25 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.24 Tue Feb 28 22:57:39 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Tue Feb 28 23:50:56 2006 @@ -39,6 +39,11 @@ /// of that FP value. FCTIDZ, FCTIWZ, + /// STFIWX - The STFIWX instruction. The first operand is an input token + /// chain, then an f64 value to store, then an address to store it to, + /// then a SRCVALUE for the address. + STFIWX, + // VMADDFP, VNMSUBFP - The VMADDFP and VNMSUBFP instructions, taking // three v4f32 operands and producing a v4f32 result. VMADDFP, VNMSUBFP, Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.177 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.178 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.177 Thu Feb 16 23:43:56 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Feb 28 23:50:56 2006 @@ -15,12 +15,25 @@ include "PPCInstrFormats.td" //===----------------------------------------------------------------------===// +// PowerPC specific type constraints. +// +def SDT_PPCstfiwx : SDTypeProfile<0, 2, [ // stfiwx + SDTCisVT<0, f64>, SDTCisPtrTy<1> +]>; +def SDT_PPCShiftOp : SDTypeProfile<1, 2, [ // PPCshl, PPCsra, PPCsrl + SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32> +]>; +def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; +def SDT_PPCRetFlag : SDTypeProfile<0, 0, []>; + +//===----------------------------------------------------------------------===// // PowerPC specific DAG Nodes. // def PPCfcfid : SDNode<"PPCISD::FCFID" , SDTFPUnaryOp, []>; def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>; def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>; +def PPCstfiwx : SDNode<"PPCISD::STFIWX", SDT_PPCstfiwx, [SDNPHasChain]>; def PPCfsel : SDNode<"PPCISD::FSEL", // Type constraint for fsel. @@ -34,19 +47,14 @@ // These nodes represent the 32-bit PPC shifts that operate on 6-bit shift // amounts. These nodes are generated by the multi-precision shift code. -def SDT_PPCShiftOp : SDTypeProfile<1, 2, [ // PPCshl, PPCsra, PPCsrl - SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32> -]>; def PPCsrl : SDNode<"PPCISD::SRL" , SDT_PPCShiftOp>; def PPCsra : SDNode<"PPCISD::SRA" , SDT_PPCShiftOp>; def PPCshl : SDNode<"PPCISD::SHL" , SDT_PPCShiftOp>; // These are target-independent nodes, but have target-specific formats. -def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeq,[SDNPHasChain]>; -def SDT_PPCRetFlag : SDTypeProfile<0, 0, []>; def retflag : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag, [SDNPHasChain, SDNPOptInFlag]>; @@ -636,9 +644,9 @@ let isStore = 1, noResults = 1 in { -def STFIWX: XForm_28<31, 983, (ops F4RC:$frS, memrr:$dst), +def STFIWX: XForm_28<31, 983, (ops F8RC:$frS, memrr:$dst), "stfiwx $frS, $dst", LdStUX, - []>; + [(PPCstfiwx F8RC:$frS, xoaddr:$dst)]>; def STFSX : XForm_28<31, 663, (ops F4RC:$frS, memrr:$dst), "stfsx $frS, $dst", LdStUX, [(store F4RC:$frS, xaddr:$dst)]>; Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.18 llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.19 --- llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.18 Wed Feb 22 14:19:42 2006 +++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp Tue Feb 28 23:50:56 2006 @@ -77,6 +77,7 @@ , Has64BitRegs(false) , HasAltivec(false) , HasFSQRT(false) + , HasSTFIWX(false) , IsAIX(false) , IsDarwin(false) { Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.66 llvm/lib/Target/PowerPC/README.txt:1.67 --- llvm/lib/Target/PowerPC/README.txt:1.66 Tue Feb 28 22:57:39 2006 +++ llvm/lib/Target/PowerPC/README.txt Tue Feb 28 23:50:56 2006 @@ -5,12 +5,6 @@ ===-------------------------------------------------------------------------=== -Use the stfiwx instruction for: - -void foo(float a, int *b) { *b = a; } - -===-------------------------------------------------------------------------=== - Support 'update' load/store instructions. These are cracked on the G5, but are still a codesize win. From lattner at cs.uiuc.edu Wed Mar 1 00:36:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 00:36:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200603010636.AAA16195@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.67 -> 1.68 --- Log message: add a note --- Diffs of the changes: (+18 -0) README.txt | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.67 llvm/lib/Target/PowerPC/README.txt:1.68 --- llvm/lib/Target/PowerPC/README.txt:1.67 Tue Feb 28 23:50:56 2006 +++ llvm/lib/Target/PowerPC/README.txt Wed Mar 1 00:36:20 2006 @@ -434,3 +434,21 @@ if (c) *a = t; } +===-------------------------------------------------------------------------=== + +This: +int test(unsigned *P) { return *P >> 24; } + +Should compile to: + +_test: + lbz r3,0(r3) + blr + +not: + +_test: + lwz r2, 0(r3) + srwi r3, r2, 24 + blr + From lattner at cs.uiuc.edu Wed Mar 1 01:14:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 01:14:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/PowerPC/or-addressing-mode.ll Message-ID: <200603010714.BAA19461@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: or-addressing-mode.ll added (r1.1) --- Log message: load (x|y) -> load (x+y) iff x and y have no common bits. --- Diffs of the changes: (+23 -0) or-addressing-mode.ll | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/or-addressing-mode.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/or-addressing-mode.ll:1.1 *** /dev/null Wed Mar 1 01:14:06 2006 --- llvm/test/Regression/CodeGen/PowerPC/or-addressing-mode.ll Wed Mar 1 01:13:56 2006 *************** *** 0 **** --- 1,23 ---- + ; RUN: llvm-as < %s | llc && + ; RUN: llvm-as < %s | llc | not grep ori && + ; RUN: llvm-as < %s | llc | not grep rlwimi + + int %test1(sbyte* %P) { ;; or -> lwzx + %tmp.2.i = cast sbyte* %P to uint + %tmp.4.i = and uint %tmp.2.i, 4294901760 + %tmp.10.i = shr uint %tmp.2.i, ubyte 5 + %tmp.11.i = and uint %tmp.10.i, 2040 + %tmp.13.i = or uint %tmp.11.i, %tmp.4.i + %tmp.14.i = cast uint %tmp.13.i to int* + %tmp.3 = load int* %tmp.14.i + ret int %tmp.3 + } + + int %test2(int %P) { ;; or -> lwz + %tmp.2 = shl int %P, ubyte 4 + %tmp.3 = or int %tmp.2, 2 + %tmp.4 = cast int %tmp.3 to int* + %tmp.5 = load int* %tmp.4 + ret int %tmp.5 + } + From lattner at cs.uiuc.edu Wed Mar 1 01:15:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 01:15:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200603010715.BAA19716@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.160 -> 1.161 --- Log message: Implement CodeGen/PowerPC/or-addressing-mode.ll, which is also PR668: http://llvm.cs.uiuc.edu/PR668 . --- Diffs of the changes: (+59 -18) PPCISelDAGToDAG.cpp | 77 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 59 insertions(+), 18 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.160 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.161 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.160 Thu Feb 23 20:13:12 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed Mar 1 01:14:48 2006 @@ -414,6 +414,10 @@ /// a base register plus a signed 16-bit displacement [r+imm]. bool PPCDAGToDAGISel::SelectAddrImm(SDOperand N, SDOperand &Disp, SDOperand &Base) { + // If this can be more profitably realized as r+r, fail. + if (SelectAddrIdx(N, Disp, Base)) + return false; + if (N.getOpcode() == ISD::ADD) { unsigned imm = 0; if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) { @@ -434,7 +438,23 @@ Base = N.getOperand(0); return true; // [&g+r] } - return false; // [r+r] + } else if (N.getOpcode() == ISD::OR) { + unsigned imm = 0; + if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) { + // If this is an or of disjoint bitfields, we can codegen this as an add + // (for better address arithmetic) if the LHS and RHS of the OR are + // provably disjoint. + uint64_t LHSKnownZero, LHSKnownOne; + PPCLowering.ComputeMaskedBits(N.getOperand(0), ~0U, + LHSKnownZero, LHSKnownOne); + if ((LHSKnownZero|~imm) == ~0U) { + // If all of the bits are known zero on the LHS or RHS, the add won't + // carry. + Base = N.getOperand(0); + Disp = getI32Imm(imm & 0xFFFF); + return true; + } + } } Disp = getI32Imm(0); if (FrameIndexSDNode *FI = dyn_cast(N)) @@ -449,35 +469,56 @@ /// be represented by [r+imm], which are preferred. bool PPCDAGToDAGISel::SelectAddrIdx(SDOperand N, SDOperand &Base, SDOperand &Index) { - // Check to see if we can represent this as an [r+imm] address instead, - // which will fail if the address is more profitably represented as an - // [r+r] address. - if (SelectAddrImm(N, Base, Index)) - return false; - + unsigned imm = 0; if (N.getOpcode() == ISD::ADD) { + if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) + return false; // r+i + if (N.getOperand(1).getOpcode() == PPCISD::Lo) + return false; // r+i + Base = N.getOperand(0); Index = N.getOperand(1); return true; + } else if (N.getOpcode() == ISD::OR) { + if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) + return false; // r+i can fold it if we can. + + // If this is an or of disjoint bitfields, we can codegen this as an add + // (for better address arithmetic) if the LHS and RHS of the OR are provably + // disjoint. + uint64_t LHSKnownZero, LHSKnownOne; + uint64_t RHSKnownZero, RHSKnownOne; + PPCLowering.ComputeMaskedBits(N.getOperand(0), ~0U, + LHSKnownZero, LHSKnownOne); + + if (LHSKnownZero) { + PPCLowering.ComputeMaskedBits(N.getOperand(1), ~0U, + RHSKnownZero, RHSKnownOne); + // If all of the bits are known zero on the LHS or RHS, the add won't + // carry. + if ((LHSKnownZero | RHSKnownZero) == ~0U) { + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; + } + } } - - Base = CurDAG->getRegister(PPC::R0, MVT::i32); - Index = N; - return true; + + return false; } /// SelectAddrIdxOnly - Given the specified addressed, force it to be /// represented as an indexed [r+r] operation. bool PPCDAGToDAGISel::SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index) { - if (N.getOpcode() == ISD::ADD) { - Base = N.getOperand(0); - Index = N.getOperand(1); - return true; + // Check to see if we can easily represent this as an [r+r] address. This + // will fail if it thinks that the address is more profitably represented as + // reg+imm, e.g. where imm = 0. + if (!SelectAddrIdx(N, Base, Index)) { + // Nope, do it the hard way. + Base = CurDAG->getRegister(PPC::R0, MVT::i32); + Index = N; } - - Base = CurDAG->getRegister(PPC::R0, MVT::i32); - Index = N; return true; } From jlaskey at apple.com Wed Mar 1 11:53:16 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 11:53:16 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603011753.LAA05543@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.22 -> 1.23 --- Log message: Basic array support. --- Diffs of the changes: (+114 -6) MachineDebugInfo.h | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 114 insertions(+), 6 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.22 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.23 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.22 Tue Feb 28 14:15:07 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Mar 1 11:53:02 2006 @@ -67,6 +67,11 @@ DI_TAG_typedef, DI_TAG_pointer, DI_TAG_reference, + DI_TAG_array, + DI_TAG_struct, + DI_TAG_union, + DI_TAG_enum, + DI_TAG_subrange, DI_TAG_const, DI_TAG_volatile, DI_TAG_restrict @@ -88,6 +93,7 @@ /// appropriate action for the type of field. virtual void Apply(int &Field) = 0; virtual void Apply(unsigned &Field) = 0; + virtual void Apply(int64_t &Field) = 0; virtual void Apply(uint64_t &Field) = 0; virtual void Apply(bool &Field) = 0; virtual void Apply(std::string &Field) = 0; @@ -130,7 +136,7 @@ // Subclasses should supply the following static methods. // Implement isa/cast/dyncast. - static bool classof(const DebugInfoDesc *) { return true; } + static bool classof(const DebugInfoDesc *) { return true; } //===--------------------------------------------------------------------===// // Subclasses should supply the following virtual methods. @@ -341,7 +347,7 @@ void setEncoding(unsigned E) { Encoding = E; } // Implement isa/cast/dyncast. - static bool classof(const BasicTypeDesc *) { return true; } + static bool classof(const BasicTypeDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { return D->getTag() == DI_TAG_basictype; } @@ -350,6 +356,14 @@ /// virtual void ApplyToFields(DIVisitor *Visitor); + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + #ifndef NDEBUG virtual void dump(); #endif @@ -371,7 +385,7 @@ void setFromType(TypeDesc *F) { FromType = F; } // Implement isa/cast/dyncast. - static bool classof(const DerivedTypeDesc *) { return true; } + static bool classof(const DerivedTypeDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { unsigned T = D->getTag(); switch (T) { @@ -382,14 +396,108 @@ case DI_TAG_volatile: case DI_TAG_restrict: return true; - default: return false; + default: break; } + return false; } /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// virtual void ApplyToFields(DIVisitor *Visitor); + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// CompositeTypeDesc - This class packages debug information associated with a +/// array/struct types (eg., arrays, struct, union, enums.) +class CompositeTypeDesc : public DerivedTypeDesc { +private: + std::vector Elements;// Information used to compose type. + +public: + CompositeTypeDesc(unsigned T); + + // Accessors + std::vector &getElements() { return Elements; } + + // Implement isa/cast/dyncast. + static bool classof(const CompositeTypeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DI_TAG_array: + case DI_TAG_struct: + case DI_TAG_union: + case DI_TAG_enum: + return true; + default: break; + } + return false; + } + + /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// SubrangeDesc - This class packages debug information associated with integer +/// value ranges. +class SubrangeDesc : public DebugInfoDesc { +private: + int64_t Lo; // Low value of range + int64_t Hi; // High value of range + +public: + SubrangeDesc(); + + // Accessors + int64_t getLo() const { return Lo; } + int64_t getHi() const { return Hi; } + void setLo(int64_t L) { Lo = L; } + void setHi(int64_t H) { Hi = H; } + + // Implement isa/cast/dyncast. + static bool classof(const SubrangeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D) { + return D->getTag() == DI_TAG_subrange; + } + + /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + #ifndef NDEBUG virtual void dump(); #endif @@ -445,7 +553,7 @@ void setLine(unsigned L) { Line = L; } // Implement isa/cast/dyncast. - static bool classof(const GlobalVariableDesc *) { return true; } + static bool classof(const GlobalVariableDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { return D->getTag() == DI_TAG_global_variable; } @@ -485,7 +593,7 @@ // FIXME - Other getters/setters. // Implement isa/cast/dyncast. - static bool classof(const SubprogramDesc *) { return true; } + static bool classof(const SubprogramDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { return D->getTag() == DI_TAG_subprogram; } From jlaskey at apple.com Wed Mar 1 11:53:16 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 11:53:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200603011753.LAA05542@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.35 -> 1.36 MachineDebugInfo.cpp updated: 1.19 -> 1.20 --- Log message: Basic array support. --- Diffs of the changes: (+197 -10) DwarfWriter.cpp | 73 +++++++++++++++++++++++++-- MachineDebugInfo.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 197 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.35 llvm/lib/CodeGen/DwarfWriter.cpp:1.36 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.35 Tue Feb 28 14:15:07 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Mar 1 11:53:02 2006 @@ -1072,12 +1072,12 @@ // Determine which derived type. unsigned T = 0; switch (DerivedTy->getTag()) { - case DI_TAG_typedef: T = DW_TAG_typedef; break; - case DI_TAG_pointer: T = DW_TAG_pointer_type; break; - case DI_TAG_reference: T = DW_TAG_reference_type; break; - case DI_TAG_const: T = DW_TAG_const_type; break; - case DI_TAG_volatile: T = DW_TAG_volatile_type; break; - case DI_TAG_restrict: T = DW_TAG_restrict_type; break; + case DI_TAG_typedef: T = DW_TAG_typedef; break; + case DI_TAG_pointer: T = DW_TAG_pointer_type; break; + case DI_TAG_reference: T = DW_TAG_reference_type; break; + case DI_TAG_const: T = DW_TAG_const_type; break; + case DI_TAG_volatile: T = DW_TAG_volatile_type; break; + case DI_TAG_restrict: T = DW_TAG_restrict_type; break; default: assert( 0 && "Unknown tag on derived type"); } @@ -1088,6 +1088,67 @@ if (TypeDesc *FromTy = DerivedTy->getFromType()) { Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Unit, FromTy)); } + } else if (CompositeTypeDesc *CompTy = dyn_cast(TyDesc)) { + // Determine which composite type. + unsigned T = 0; + switch (CompTy->getTag()) { + case DI_TAG_array: T = DW_TAG_array_type; break; + case DI_TAG_struct: T = DW_TAG_structure_type; break; + case DI_TAG_union: T = DW_TAG_union_type; break; + case DI_TAG_enum: T = DW_TAG_enumeration_type; break; + default: assert( 0 && "Unknown tag on composite type"); + } + + // Create specific DIE. + Slot = Ty = new DIE(T); + std::vector &Elements = CompTy->getElements(); + + switch (CompTy->getTag()) { + case DI_TAG_array: { + // Add element type. + if (TypeDesc *FromTy = CompTy->getFromType()) { + Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Unit, FromTy)); + } + // Don't emit size attribute. + Size = 0; + + // Construct an anonymous type for index type. + DIE *IndexTy = new DIE(DW_TAG_base_type); + IndexTy->AddUInt(DW_AT_byte_size, 0, 4); + IndexTy->AddUInt(DW_AT_encoding, DW_FORM_data1, DW_ATE_signed); + // Add to context. + Unit->getDie()->AddChild(IndexTy); + + // Add subranges to array type. + for(unsigned i = 0, N = Elements.size(); i < N; ++i) { + SubrangeDesc *SRD = cast(Elements[i]); + int64_t Lo = SRD->getLo(); + int64_t Hi = SRD->getHi(); + DIE *Subrange = new DIE(DW_TAG_subrange_type); + + // If a range is available. + if (Lo != Hi) { + Subrange->AddDIEntry(DW_AT_type, DW_FORM_ref4, IndexTy); + // Only add low if non-zero. + if (Lo) Subrange->AddUInt(DW_AT_lower_bound, 0, Lo); + Subrange->AddUInt(DW_AT_upper_bound, 0, Hi); + } + Ty->AddChild(Subrange); + } + + break; + } + case DI_TAG_struct: { + break; + } + case DI_TAG_union: { + break; + } + case DI_TAG_enum: { + break; + } + default: break; + } } assert(Ty && "Type not supported yet"); Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.19 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.20 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.19 Tue Feb 28 14:15:07 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Mar 1 11:53:02 2006 @@ -197,6 +197,7 @@ /// virtual void Apply(int &Field) { ++Count; } virtual void Apply(unsigned &Field) { ++Count; } + virtual void Apply(int64_t &Field) { ++Count; } virtual void Apply(uint64_t &Field) { ++Count; } virtual void Apply(bool &Field) { ++Count; } virtual void Apply(std::string &Field) { ++Count; } @@ -234,6 +235,10 @@ Constant *C = CI->getOperand(I++); Field = cast(C)->getValue(); } + virtual void Apply(int64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getValue(); + } virtual void Apply(uint64_t &Field) { Constant *C = CI->getOperand(I++); Field = cast(C)->getValue(); @@ -290,6 +295,9 @@ virtual void Apply(unsigned &Field) { Elements.push_back(ConstantUInt::get(Type::UIntTy, Field)); } + virtual void Apply(int64_t &Field) { + Elements.push_back(ConstantSInt::get(Type::IntTy, Field)); + } virtual void Apply(uint64_t &Field) { Elements.push_back(ConstantUInt::get(Type::UIntTy, Field)); } @@ -337,7 +345,11 @@ } Constant *CA = ConstantArray::get(AT, ArrayElements); - Constant *CAE = ConstantExpr::getCast(CA, EmptyTy); + GlobalVariable *CAGV = new GlobalVariable(AT, true, + GlobalValue::InternalLinkage, + CA, "llvm.dbg.array", + SR.getModule()); + Constant *CAE = ConstantExpr::getCast(CAGV, EmptyTy); Elements.push_back(CAE); } }; @@ -365,6 +377,9 @@ virtual void Apply(unsigned &Field) { Fields.push_back(Type::UIntTy); } + virtual void Apply(int64_t &Field) { + Fields.push_back(Type::IntTy); + } virtual void Apply(uint64_t &Field) { Fields.push_back(Type::UIntTy); } @@ -422,6 +437,10 @@ Constant *C = CI->getOperand(I++); IsValid = IsValid && isa(C); } + virtual void Apply(int64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C); + } virtual void Apply(uint64_t &Field) { Constant *C = CI->getOperand(I++); IsValid = IsValid && isa(C); @@ -491,6 +510,11 @@ case DI_TAG_const: case DI_TAG_volatile: case DI_TAG_restrict: return new DerivedTypeDesc(Tag); + case DI_TAG_array: + case DI_TAG_struct: + case DI_TAG_union: + case DI_TAG_enum: return new CompositeTypeDesc(Tag); + case DI_TAG_subrange: return new SubrangeDesc(); default: break; } return NULL; @@ -681,6 +705,18 @@ Visitor->Apply(Encoding); } +/// getDescString - Return a string used to compose global names and labels. +/// +const char *BasicTypeDesc::getDescString() const { + return "llvm.dbg.basictype"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *BasicTypeDesc::getTypeString() const { + return "llvm.dbg.basictype.type"; +} + #ifndef NDEBUG void BasicTypeDesc::dump() { std::cerr << getDescString() << " " @@ -691,14 +727,13 @@ << "Encoding(" << Encoding << ")\n"; } #endif + //===----------------------------------------------------------------------===// DerivedTypeDesc::DerivedTypeDesc(unsigned T) : TypeDesc(T) , FromType(NULL) -{ - assert(classof((const DebugInfoDesc *)this) && "Unknown derived type."); -} +{} /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// @@ -708,6 +743,18 @@ Visitor->Apply((DebugInfoDesc *&)FromType); } +/// getDescString - Return a string used to compose global names and labels. +/// +const char *DerivedTypeDesc::getDescString() const { + return "llvm.dbg.derivedtype"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *DerivedTypeDesc::getTypeString() const { + return "llvm.dbg.derivedtype.type"; +} + #ifndef NDEBUG void DerivedTypeDesc::dump() { std::cerr << getDescString() << " " @@ -723,6 +770,85 @@ //===----------------------------------------------------------------------===// +CompositeTypeDesc::CompositeTypeDesc(unsigned T) +: DerivedTypeDesc(T) +, Elements() +{} + +/// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. +/// +void CompositeTypeDesc::ApplyToFields(DIVisitor *Visitor) { + DerivedTypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(Elements); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *CompositeTypeDesc::getDescString() const { + return "llvm.dbg.compositetype"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *CompositeTypeDesc::getTypeString() const { + return "llvm.dbg.compositetype.type"; +} + +#ifndef NDEBUG +void CompositeTypeDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << getFromType() << "), " + << "Elements.size(" << Elements.size() << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +SubrangeDesc::SubrangeDesc() +: DebugInfoDesc(DI_TAG_subrange) +, Lo(0) +, Hi(0) +{} + +/// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. +/// +void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Lo); + Visitor->Apply(Hi); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *SubrangeDesc::getDescString() const { + return "llvm.dbg.subrange"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *SubrangeDesc::getTypeString() const { + return "llvm.dbg.subrange.type"; +} + +#ifndef NDEBUG +void SubrangeDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Lo(" << Lo << "), " + << "Hi(" << Hi << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + GlobalDesc::GlobalDesc(unsigned T) : AnchoredDesc(T) , Context(0) From jlaskey at apple.com Wed Mar 1 12:13:18 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 12:13:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200603011813.MAA05850@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.36 -> 1.37 --- Log message: I guess I can handle large type sizes. --- Diffs of the changes: (+1 -2) DwarfWriter.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.36 llvm/lib/CodeGen/DwarfWriter.cpp:1.37 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.36 Wed Mar 1 11:53:02 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Mar 1 12:13:05 2006 @@ -1058,8 +1058,7 @@ // Get core information. const std::string &Name = TyDesc->getName(); - // FIXME - handle larger sizes. - unsigned Size = TyDesc->getSize() >> 3; + uint64_t Size = TyDesc->getSize() >> 3; DIE *Ty = NULL; From jlaskey at apple.com Wed Mar 1 12:20:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 12:20:43 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h Message-ID: <200603011820.MAA05922@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.27 -> 1.28 --- Log message: Use context and not compile unit. --- Diffs of the changes: (+2 -2) DwarfWriter.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.27 llvm/include/llvm/CodeGen/DwarfWriter.h:1.28 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.27 Mon Feb 27 11:27:12 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Wed Mar 1 12:20:30 2006 @@ -296,13 +296,13 @@ /// NewBasicType - Creates a new basic type if necessary, then adds to the /// owner. /// FIXME - Should never be needed. - DIE *NewBasicType(CompileUnit *Unit, Type *Ty); + DIE *NewBasicType(DIE *Context, Type *Ty); private: /// NewType - Create a new type DIE. /// - DIE *DwarfWriter::NewType(CompileUnit *Unit, TypeDesc *TyDesc); + DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc); /// NewCompileUnit - Create new compile unit and it's die. /// From jlaskey at apple.com Wed Mar 1 12:20:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 12:20:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200603011820.MAA05926@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.37 -> 1.38 --- Log message: Use context and not compile unit. --- Diffs of the changes: (+13 -11) DwarfWriter.cpp | 24 +++++++++++++----------- 1 files changed, 13 insertions(+), 11 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.37 llvm/lib/CodeGen/DwarfWriter.cpp:1.38 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.37 Wed Mar 1 12:13:05 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Mar 1 12:20:30 2006 @@ -967,7 +967,7 @@ /// NewBasicType - Creates a new basic type if necessary, then adds to the /// owner. /// FIXME - Should never be needed. -DIE *DwarfWriter::NewBasicType(CompileUnit *Unit, Type *Ty) { +DIE *DwarfWriter::NewBasicType(DIE *Context, Type *Ty) { DIE *&Slot = TypeToDieMap[Ty]; if (Slot) return Slot; @@ -1040,17 +1040,19 @@ Slot->AddUInt (DW_AT_byte_size, 0, Size); Slot->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); - // Add to context owner. - Unit->getDie()->AddChild(Slot); + // Add to context. + Context->AddChild(Slot); return Slot; } /// NewType - Create a new type DIE. /// -DIE *DwarfWriter::NewType(CompileUnit *Unit, TypeDesc *TyDesc) { +DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc) { // FIXME - hack to get around NULL types short term. - if (!TyDesc) return NewBasicType(Unit, Type::IntTy); + if (!TyDesc) return NewBasicType(Context, Type::IntTy); + + // FIXME - Should handle other contexts that compile units. // Check for pre-existence. DIE *&Slot = DescToDieMap[TyDesc]; @@ -1085,7 +1087,7 @@ // Map to main type, void will not have a type. if (TypeDesc *FromTy = DerivedTy->getFromType()) { - Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Unit, FromTy)); + Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); } } else if (CompositeTypeDesc *CompTy = dyn_cast(TyDesc)) { // Determine which composite type. @@ -1106,7 +1108,7 @@ case DI_TAG_array: { // Add element type. if (TypeDesc *FromTy = CompTy->getFromType()) { - Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Unit, FromTy)); + Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); } // Don't emit size attribute. Size = 0; @@ -1116,7 +1118,7 @@ IndexTy->AddUInt(DW_AT_byte_size, 0, 4); IndexTy->AddUInt(DW_AT_encoding, DW_FORM_data1, DW_ATE_signed); // Add to context. - Unit->getDie()->AddChild(IndexTy); + Context->AddChild(IndexTy); // Add subranges to array type. for(unsigned i = 0, N = Elements.size(); i < N; ++i) { @@ -1166,7 +1168,7 @@ } // Add to context owner. - Unit->getDie()->AddChild(Ty); + Context->AddChild(Ty); return Slot; } @@ -1226,7 +1228,7 @@ unsigned Line = GVD->getLine(); // Get the global's type. - DIE *Type = NewType(Unit, GVD->getTypeDesc()); + DIE *Type = NewType(Unit->getDie(), GVD->getTypeDesc()); // Create the globale variable DIE. DIE *VariableDie = new DIE(DW_TAG_variable); @@ -1269,7 +1271,7 @@ unsigned Line = 1; // FIXME - faking the type for the time being. - DIE *Type = NewBasicType(Unit, Type::IntTy); + DIE *Type = NewBasicType(Unit->getDie(), Type::IntTy); DIE *SubprogramDie = new DIE(DW_TAG_subprogram); SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name); From lattner at cs.uiuc.edu Wed Mar 1 13:55:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 13:55:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200603011955.NAA11442@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.117 -> 1.118 --- Log message: Fix a typo evan noticed --- Diffs of the changes: (+1 -1) DAGCombiner.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.117 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.118 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.117 Tue Feb 28 22:53:38 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Mar 1 13:55:35 2006 @@ -113,7 +113,7 @@ private: /// SimplifyDemandedBits - Check the specified integer node value to see if - /// it can be simplified or if things is uses can be simplified by bit + /// it can be simplified or if things it uses can be simplified by bit /// propagation. If so, return true. bool SimplifyDemandedBits(SDOperand Op) { TargetLowering::TargetLoweringOpt TLO(DAG); From jlaskey at apple.com Wed Mar 1 14:39:49 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 14:39:49 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603012039.OAA13233@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.23 -> 1.24 --- Log message: Switch back to using actual dwarf tags. Simplifies code without loss to other debug forms. --- Diffs of the changes: (+16 -72) MachineDebugInfo.h | 88 +++++++++-------------------------------------------- 1 files changed, 16 insertions(+), 72 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.23 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.24 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.23 Wed Mar 1 11:53:02 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Mar 1 14:39:35 2006 @@ -56,25 +56,6 @@ enum { LLVMDebugVersion = 1, // Current version of debug information. - DIInvalid = ~0U, // Invalid result indicator. - - // DebugInfoDesc type identifying tags. - DI_TAG_anchor = 0, - DI_TAG_compile_unit, - DI_TAG_global_variable, - DI_TAG_subprogram, - DI_TAG_basictype, - DI_TAG_typedef, - DI_TAG_pointer, - DI_TAG_reference, - DI_TAG_array, - DI_TAG_struct, - DI_TAG_union, - DI_TAG_enum, - DI_TAG_subrange, - DI_TAG_const, - DI_TAG_volatile, - DI_TAG_restrict }; //===----------------------------------------------------------------------===// @@ -166,23 +147,15 @@ std::string Name; // Anchor type string. public: - AnchorDesc() - : DebugInfoDesc(DI_TAG_anchor) - , Name("") - {} - AnchorDesc(const std::string &N) - : DebugInfoDesc(DI_TAG_anchor) - , Name(N) - {} + AnchorDesc(); + AnchorDesc(const std::string &N); // Accessors const std::string &getName() const { return Name; } // Implement isa/cast/dyncast. static bool classof(const AnchorDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_anchor; - } + static bool classof(const DebugInfoDesc *D); /// getLinkage - get linkage appropriate for this type of descriptor. /// @@ -259,9 +232,7 @@ // Implement isa/cast/dyncast. static bool classof(const CompileUnitDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_compile_unit; - } + static bool classof(const DebugInfoDesc *D); /// DebugVersionFromGlobal - Returns the version number from a compile unit /// GlobalVariable. Return DIIValid if operand is not an unsigned int. @@ -348,9 +319,7 @@ // Implement isa/cast/dyncast. static bool classof(const BasicTypeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_basictype; - } + static bool classof(const DebugInfoDesc *D); /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. /// @@ -386,20 +355,7 @@ // Implement isa/cast/dyncast. static bool classof(const DerivedTypeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - unsigned T = D->getTag(); - switch (T) { - case DI_TAG_typedef: - case DI_TAG_pointer: - case DI_TAG_reference: - case DI_TAG_const: - case DI_TAG_volatile: - case DI_TAG_restrict: - return true; - default: break; - } - return false; - } + static bool classof(const DebugInfoDesc *D); /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// @@ -433,18 +389,7 @@ // Implement isa/cast/dyncast. static bool classof(const CompositeTypeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - unsigned T = D->getTag(); - switch (T) { - case DI_TAG_array: - case DI_TAG_struct: - case DI_TAG_union: - case DI_TAG_enum: - return true; - default: break; - } - return false; - } + static bool classof(const DebugInfoDesc *D); /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. /// @@ -482,9 +427,7 @@ // Implement isa/cast/dyncast. static bool classof(const SubrangeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_subrange; - } + static bool classof(const DebugInfoDesc *D); /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. /// @@ -554,9 +497,7 @@ // Implement isa/cast/dyncast. static bool classof(const GlobalVariableDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_global_variable; - } + static bool classof(const DebugInfoDesc *D); /// ApplyToFields - Target the visitor to the fields of the /// GlobalVariableDesc. @@ -594,9 +535,7 @@ // Implement isa/cast/dyncast. static bool classof(const SubprogramDesc *) { return true; } - static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_subprogram; - } + static bool classof(const DebugInfoDesc *D); /// ApplyToFields - Target the visitor to the fields of the SubprogramDesc. /// @@ -873,7 +812,12 @@ getGlobalVariablesUsing(M, Desc.getAnchorString()); std::vector AnchoredDescs; for (unsigned i = 0, N = Globals.size(); i < N; ++i) { - AnchoredDescs.push_back(cast(DR.Deserialize(Globals[i]))); + GlobalVariable *GV = Globals[i]; + // FIXME - Tag check only necessary for bring up (changed tag values.) + unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); + if (Tag == Desc.getTag()) { + AnchoredDescs.push_back(cast(DR.Deserialize(GV))); + } } return AnchoredDescs; From jlaskey at apple.com Wed Mar 1 14:39:48 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 14:39:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200603012039.OAA13229@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.38 -> 1.39 MachineDebugInfo.cpp updated: 1.20 -> 1.21 --- Log message: Switch back to using actual dwarf tags. Simplifies code without loss to other debug forms. --- Diffs of the changes: (+103 -55) DwarfWriter.cpp | 34 ++----------- MachineDebugInfo.cpp | 124 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 103 insertions(+), 55 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.38 llvm/lib/CodeGen/DwarfWriter.cpp:1.39 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.38 Wed Mar 1 12:20:30 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Mar 1 14:39:35 2006 @@ -1070,42 +1070,20 @@ unsigned Encoding = BasicTy->getEncoding(); Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); } else if (DerivedTypeDesc *DerivedTy = dyn_cast(TyDesc)) { - // Determine which derived type. - unsigned T = 0; - switch (DerivedTy->getTag()) { - case DI_TAG_typedef: T = DW_TAG_typedef; break; - case DI_TAG_pointer: T = DW_TAG_pointer_type; break; - case DI_TAG_reference: T = DW_TAG_reference_type; break; - case DI_TAG_const: T = DW_TAG_const_type; break; - case DI_TAG_volatile: T = DW_TAG_volatile_type; break; - case DI_TAG_restrict: T = DW_TAG_restrict_type; break; - default: assert( 0 && "Unknown tag on derived type"); - } - // Create specific DIE. - Slot = Ty = new DIE(T); + Slot = Ty = new DIE(DerivedTy->getTag()); // Map to main type, void will not have a type. if (TypeDesc *FromTy = DerivedTy->getFromType()) { Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); } } else if (CompositeTypeDesc *CompTy = dyn_cast(TyDesc)) { - // Determine which composite type. - unsigned T = 0; - switch (CompTy->getTag()) { - case DI_TAG_array: T = DW_TAG_array_type; break; - case DI_TAG_struct: T = DW_TAG_structure_type; break; - case DI_TAG_union: T = DW_TAG_union_type; break; - case DI_TAG_enum: T = DW_TAG_enumeration_type; break; - default: assert( 0 && "Unknown tag on composite type"); - } - // Create specific DIE. - Slot = Ty = new DIE(T); + Slot = Ty = new DIE(CompTy->getTag()); std::vector &Elements = CompTy->getElements(); switch (CompTy->getTag()) { - case DI_TAG_array: { + case DW_TAG_array_type: { // Add element type. if (TypeDesc *FromTy = CompTy->getFromType()) { Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); @@ -1139,13 +1117,13 @@ break; } - case DI_TAG_struct: { + case DW_TAG_structure_type: { break; } - case DI_TAG_union: { + case DW_TAG_union_type: { break; } - case DI_TAG_enum: { + case DW_TAG_enumeration_type: { break; } default: break; Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.20 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.21 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.20 Wed Mar 1 11:53:02 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Mar 1 14:39:36 2006 @@ -20,6 +20,7 @@ #include using namespace llvm; +using namespace llvm::dwarf; // Handle the Pass registration stuff necessary to use TargetData's. namespace { @@ -492,29 +493,29 @@ /// GlobalVariable. unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) { ConstantUInt *C = getUIntOperand(GV, 0); - return C ? (unsigned)C->getValue() : (unsigned)DIInvalid; + return C ? (unsigned)C->getValue() : (unsigned)DW_TAG_invalid; } /// DescFactory - Create an instance of debug info descriptor based on Tag. /// Return NULL if not a recognized Tag. DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) { switch (Tag) { - case DI_TAG_anchor: return new AnchorDesc(); - case DI_TAG_compile_unit: return new CompileUnitDesc(); - case DI_TAG_global_variable: return new GlobalVariableDesc(); - case DI_TAG_subprogram: return new SubprogramDesc(); - case DI_TAG_basictype: return new BasicTypeDesc(); - case DI_TAG_typedef: - case DI_TAG_pointer: - case DI_TAG_reference: - case DI_TAG_const: - case DI_TAG_volatile: - case DI_TAG_restrict: return new DerivedTypeDesc(Tag); - case DI_TAG_array: - case DI_TAG_struct: - case DI_TAG_union: - case DI_TAG_enum: return new CompositeTypeDesc(Tag); - case DI_TAG_subrange: return new SubrangeDesc(); + case DW_TAG_anchor: return new AnchorDesc(); + case DW_TAG_compile_unit: return new CompileUnitDesc(); + case DW_TAG_variable: return new GlobalVariableDesc(); + case DW_TAG_subprogram: return new SubprogramDesc(); + case DW_TAG_base_type: return new BasicTypeDesc(); + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: return new DerivedTypeDesc(Tag); + case DW_TAG_array_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: return new CompositeTypeDesc(Tag); + case DW_TAG_subrange_type: return new SubrangeDesc(); default: break; } return NULL; @@ -534,6 +535,20 @@ //===----------------------------------------------------------------------===// +AnchorDesc::AnchorDesc() +: DebugInfoDesc(DW_TAG_anchor) +, Name("") +{} +AnchorDesc::AnchorDesc(const std::string &N) +: DebugInfoDesc(DW_TAG_anchor) +, Name(N) +{} + +// Implement isa/cast/dyncast. +bool AnchorDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_anchor; +} + /// getLinkage - get linkage appropriate for this type of descriptor. /// GlobalValue::LinkageTypes AnchorDesc::getLinkage() const { @@ -586,7 +601,7 @@ //===----------------------------------------------------------------------===// CompileUnitDesc::CompileUnitDesc() -: AnchoredDesc(DI_TAG_compile_unit) +: AnchoredDesc(DW_TAG_compile_unit) , DebugVersion(LLVMDebugVersion) , Language(0) , FileName("") @@ -594,11 +609,16 @@ , Producer("") {} +// Implement isa/cast/dyncast. +bool CompileUnitDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_compile_unit; +} + /// DebugVersionFromGlobal - Returns the version number from a compile unit /// GlobalVariable. unsigned CompileUnitDesc::DebugVersionFromGlobal(GlobalVariable *GV) { ConstantUInt *C = getUIntOperand(GV, 2); - return C ? (unsigned)C->getValue() : (unsigned)DIInvalid; + return C ? (unsigned)C->getValue() : (unsigned)DW_TAG_invalid; } /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. @@ -693,10 +713,15 @@ //===----------------------------------------------------------------------===// BasicTypeDesc::BasicTypeDesc() -: TypeDesc(DI_TAG_basictype) +: TypeDesc(DW_TAG_base_type) , Encoding(0) {} +// Implement isa/cast/dyncast. +bool BasicTypeDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_base_type; +} + /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. /// void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { @@ -735,6 +760,22 @@ , FromType(NULL) {} +// Implement isa/cast/dyncast. +bool DerivedTypeDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + return true; + default: break; + } + return false; +} + /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) { @@ -775,6 +816,20 @@ , Elements() {} +// Implement isa/cast/dyncast. +bool CompositeTypeDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_array_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + return true; + default: break; + } + return false; +} + /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. /// void CompositeTypeDesc::ApplyToFields(DIVisitor *Visitor) { @@ -812,11 +867,16 @@ //===----------------------------------------------------------------------===// SubrangeDesc::SubrangeDesc() -: DebugInfoDesc(DI_TAG_subrange) +: DebugInfoDesc(DW_TAG_subrange_type) , Lo(0) , Hi(0) {} +// Implement isa/cast/dyncast. +bool SubrangeDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_subrange_type; +} + /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. /// void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) { @@ -873,10 +933,15 @@ //===----------------------------------------------------------------------===// GlobalVariableDesc::GlobalVariableDesc() -: GlobalDesc(DI_TAG_global_variable) +: GlobalDesc(DW_TAG_variable) , Global(NULL) {} +// Implement isa/cast/dyncast. +bool GlobalVariableDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_variable; +} + /// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc. /// void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) { @@ -921,9 +986,14 @@ //===----------------------------------------------------------------------===// SubprogramDesc::SubprogramDesc() -: GlobalDesc(DI_TAG_subprogram) +: GlobalDesc(DW_TAG_subprogram) {} +// Implement isa/cast/dyncast. +bool SubprogramDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_subprogram; +} + /// ApplyToFields - Target the visitor to the fields of the /// SubprogramDesc. void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) { @@ -977,7 +1047,7 @@ unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); // Get the debug version if a compile unit. - if (Tag == DI_TAG_compile_unit) { + if (Tag == DW_TAG_compile_unit) { DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV); } @@ -1123,12 +1193,12 @@ // Get the Tag unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); - if (Tag == DIInvalid) return false; + if (Tag == DW_TAG_invalid) return false; // If a compile unit we need the debug version. - if (Tag == DI_TAG_compile_unit) { + if (Tag == DW_TAG_compile_unit) { DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV); - if (DebugVersion == DIInvalid) return false; + if (DebugVersion == DW_TAG_invalid) return false; } // Construct an empty DebugInfoDesc. From jlaskey at apple.com Wed Mar 1 14:39:49 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 14:39:49 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/Dwarf.h Message-ID: <200603012039.OAA13237@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: Dwarf.h updated: 1.3 -> 1.4 --- Log message: Switch back to using actual dwarf tags. Simplifies code without loss to other debug forms. --- Diffs of the changes: (+10 -0) Dwarf.h | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/include/llvm/Support/Dwarf.h diff -u llvm/include/llvm/Support/Dwarf.h:1.3 llvm/include/llvm/Support/Dwarf.h:1.4 --- llvm/include/llvm/Support/Dwarf.h:1.3 Mon Feb 27 16:37:23 2006 +++ llvm/include/llvm/Support/Dwarf.h Wed Mar 1 14:39:35 2006 @@ -24,6 +24,16 @@ // Dwarf constants as gleaned from the DWARF Debugging Information Format V.3 // reference manual http://dwarf.freestandards.org . // + +// Do not mix the following two enumerations sets. DW_TAG_invalid changes the +// enumeration base type. + +enum llvm_dwarf_constants { + // llvm mock tags + DW_TAG_invalid = ~0U, // Tag for invalid results. + DW_TAG_anchor = 0, // Tag for descriptor anchors. +}; + enum dwarf_constants { DWARF_VERSION = 2, From jlaskey at apple.com Wed Mar 1 14:48:32 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 14:48:32 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/Dwarf.h Message-ID: <200603012048.OAA13318@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: Dwarf.h updated: 1.4 -> 1.5 --- Log message: Remove comma from enum list. --- Diffs of the changes: (+1 -1) Dwarf.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Support/Dwarf.h diff -u llvm/include/llvm/Support/Dwarf.h:1.4 llvm/include/llvm/Support/Dwarf.h:1.5 --- llvm/include/llvm/Support/Dwarf.h:1.4 Wed Mar 1 14:39:35 2006 +++ llvm/include/llvm/Support/Dwarf.h Wed Mar 1 14:48:20 2006 @@ -31,7 +31,7 @@ enum llvm_dwarf_constants { // llvm mock tags DW_TAG_invalid = ~0U, // Tag for invalid results. - DW_TAG_anchor = 0, // Tag for descriptor anchors. + DW_TAG_anchor = 0 // Tag for descriptor anchors. }; enum dwarf_constants { From jlaskey at apple.com Wed Mar 1 14:49:56 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 14:49:56 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603012049.OAA13334@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.24 -> 1.25 --- Log message: Remove extra comma from enum list. --- Diffs of the changes: (+1 -1) MachineDebugInfo.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.24 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.25 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.24 Wed Mar 1 14:39:35 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Mar 1 14:49:44 2006 @@ -55,7 +55,7 @@ // Debug info constants. enum { - LLVMDebugVersion = 1, // Current version of debug information. + LLVMDebugVersion = 1 // Current version of debug information. }; //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Wed Mar 1 15:47:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 15:47:05 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Generic/2006-03-01-dagcombineinfloop.ll Message-ID: <200603012147.PAA14253@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: 2006-03-01-dagcombineinfloop.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+98 -0) 2006-03-01-dagcombineinfloop.ll | 98 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 98 insertions(+) Index: llvm/test/Regression/CodeGen/Generic/2006-03-01-dagcombineinfloop.ll diff -c /dev/null llvm/test/Regression/CodeGen/Generic/2006-03-01-dagcombineinfloop.ll:1.1 *** /dev/null Wed Mar 1 15:47:03 2006 --- llvm/test/Regression/CodeGen/Generic/2006-03-01-dagcombineinfloop.ll Wed Mar 1 15:46:53 2006 *************** *** 0 **** --- 1,98 ---- + ; RUN: llvm-as < %s | llc + ; Infinite loop in the dag combiner, reduced from 176.gcc. + + %struct._obstack_chunk = type { sbyte*, %struct._obstack_chunk*, [4 x sbyte] } + %struct.anon = type { int } + %struct.lang_decl = type opaque + %struct.lang_type = type { int, [1 x %struct.tree_node*] } + %struct.obstack = type { int, %struct._obstack_chunk*, sbyte*, sbyte*, sbyte*, int, int, %struct._obstack_chunk* (...)*, void (...)*, sbyte*, ubyte } + %struct.rtx_def = type { ushort, ubyte, ubyte, [1 x %struct.anon] } + %struct.tree_common = type { %struct.tree_node*, %struct.tree_node*, ubyte, ubyte, ubyte, ubyte } + %struct.tree_decl = type { [12 x sbyte], sbyte*, int, %struct.tree_node*, uint, ubyte, ubyte, ubyte, ubyte, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, %struct.anon, { %struct.rtx_def* }, %struct.tree_node*, %struct.lang_decl* } + %struct.tree_list = type { [12 x sbyte], %struct.tree_node*, %struct.tree_node* } + %struct.tree_node = type { %struct.tree_decl } + %struct.tree_type = type { [12 x sbyte], %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, uint, ubyte, ubyte, ubyte, ubyte, uint, %struct.tree_node*, %struct.tree_node*, %struct.anon, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.obstack*, %struct.lang_type* } + %void_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + %char_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + %short_integer_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + %short_unsigned_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + %float_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + %signed_char_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + %unsigned_char_type_node = external global %struct.tree_node* ; <%struct.tree_node**> [#uses=1] + + implementation ; Functions: + + fastcc int %self_promoting_args_p(%struct.tree_node* %parms) { + entry: + %tmp915 = seteq %struct.tree_node* %parms, null ; [#uses=1] + br bool %tmp915, label %return, label %cond_true92.preheader + + cond_true: ; preds = %cond_true92 + %tmp9.not = setne %struct.tree_node* %tmp2, %tmp7 ; [#uses=1] + %tmp14 = seteq %struct.tree_node* %tmp2, null ; [#uses=1] + %bothcond = or bool %tmp9.not, %tmp14 ; [#uses=1] + br bool %bothcond, label %return, label %cond_next18 + + cond_next12: ; preds = %cond_true92 + %tmp14.old = seteq %struct.tree_node* %tmp2, null ; [#uses=1] + br bool %tmp14.old, label %return, label %cond_next18 + + cond_next18: ; preds = %cond_next12, %cond_true + %tmp20 = cast %struct.tree_node* %tmp2 to %struct.tree_type* ; <%struct.tree_type*> [#uses=1] + %tmp21 = getelementptr %struct.tree_type* %tmp20, int 0, uint 17 ; <%struct.tree_node**> [#uses=1] + %tmp22 = load %struct.tree_node** %tmp21 ; <%struct.tree_node*> [#uses=6] + %tmp24 = seteq %struct.tree_node* %tmp22, %tmp23 ; [#uses=1] + br bool %tmp24, label %return, label %cond_next28 + + cond_next28: ; preds = %cond_next18 + %tmp30 = cast %struct.tree_node* %tmp2 to %struct.tree_common* ; <%struct.tree_common*> [#uses=1] + %tmp = getelementptr %struct.tree_common* %tmp30, int 0, uint 2 ; [#uses=1] + %tmp = cast ubyte* %tmp to uint* ; [#uses=1] + %tmp = load uint* %tmp ; [#uses=1] + %tmp32 = cast uint %tmp to ubyte ; [#uses=1] + %tmp33 = seteq ubyte %tmp32, 7 ; [#uses=1] + br bool %tmp33, label %cond_true34, label %cond_next84 + + cond_true34: ; preds = %cond_next28 + %tmp40 = seteq %struct.tree_node* %tmp22, %tmp39 ; [#uses=1] + %tmp49 = seteq %struct.tree_node* %tmp22, %tmp48 ; [#uses=1] + %bothcond6 = or bool %tmp40, %tmp49 ; [#uses=1] + %tmp58 = seteq %struct.tree_node* %tmp22, %tmp57 ; [#uses=1] + %bothcond7 = or bool %bothcond6, %tmp58 ; [#uses=1] + %tmp67 = seteq %struct.tree_node* %tmp22, %tmp66 ; [#uses=1] + %bothcond8 = or bool %bothcond7, %tmp67 ; [#uses=1] + %tmp76 = seteq %struct.tree_node* %tmp22, %tmp75 ; [#uses=1] + %bothcond9 = or bool %bothcond8, %tmp76 ; [#uses=2] + %brmerge = or bool %bothcond9, %tmp ; [#uses=1] + %bothcond9 = cast bool %bothcond9 to int ; [#uses=1] + %.mux = xor int %bothcond9, 1 ; [#uses=1] + br bool %brmerge, label %return, label %cond_true92 + + cond_next84: ; preds = %cond_next28 + br bool %tmp, label %return, label %cond_true92 + + cond_true92.preheader: ; preds = %entry + %tmp7 = load %struct.tree_node** %void_type_node ; <%struct.tree_node*> [#uses=1] + %tmp23 = load %struct.tree_node** %float_type_node ; <%struct.tree_node*> [#uses=1] + %tmp39 = load %struct.tree_node** %char_type_node ; <%struct.tree_node*> [#uses=1] + %tmp48 = load %struct.tree_node** %signed_char_type_node ; <%struct.tree_node*> [#uses=1] + %tmp57 = load %struct.tree_node** %unsigned_char_type_node ; <%struct.tree_node*> [#uses=1] + %tmp66 = load %struct.tree_node** %short_integer_type_node ; <%struct.tree_node*> [#uses=1] + %tmp75 = load %struct.tree_node** %short_unsigned_type_node ; <%struct.tree_node*> [#uses=1] + br label %cond_true92 + + cond_true92: ; preds = %cond_true92.preheader, %cond_next84, %cond_true34 + %t.0.0 = phi %struct.tree_node* [ %parms, %cond_true92.preheader ], [ %tmp6, %cond_true34 ], [ %tmp6, %cond_next84 ] ; <%struct.tree_node*> [#uses=2] + %tmp = cast %struct.tree_node* %t.0.0 to %struct.tree_list* ; <%struct.tree_list*> [#uses=1] + %tmp = getelementptr %struct.tree_list* %tmp, int 0, uint 2 ; <%struct.tree_node**> [#uses=1] + %tmp2 = load %struct.tree_node** %tmp ; <%struct.tree_node*> [#uses=5] + %tmp4 = cast %struct.tree_node* %t.0.0 to %struct.tree_common* ; <%struct.tree_common*> [#uses=1] + %tmp5 = getelementptr %struct.tree_common* %tmp4, int 0, uint 0 ; <%struct.tree_node**> [#uses=1] + %tmp6 = load %struct.tree_node** %tmp5 ; <%struct.tree_node*> [#uses=3] + %tmp = seteq %struct.tree_node* %tmp6, null ; [#uses=3] + br bool %tmp, label %cond_true, label %cond_next12 + + return: ; preds = %cond_next84, %cond_true34, %cond_next18, %cond_next12, %cond_true, %entry + %retval.0 = phi int [ 1, %entry ], [ 1, %cond_next84 ], [ %.mux, %cond_true34 ], [ 0, %cond_next18 ], [ 0, %cond_next12 ], [ 0, %cond_true ] ; [#uses=1] + ret int %retval.0 + } From lattner at cs.uiuc.edu Wed Mar 1 15:47:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 15:47:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200603012147.PAA14288@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.118 -> 1.119 --- Log message: Fix CodeGen/Generic/2006-03-01-dagcombineinfloop.ll, an infinite loop in the dag combiner on 176.gcc on x86. --- Diffs of the changes: (+9 -4) DAGCombiner.cpp | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.118 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.119 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.118 Wed Mar 1 13:55:35 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Mar 1 15:47:21 2006 @@ -1018,14 +1018,19 @@ return N1; // fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits. if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) { - unsigned InBits = MVT::getSizeInBits(N0.getOperand(0).getValueType()); + unsigned InMask = MVT::getIntVTBitMask(N0.getOperand(0).getValueType()); if (TLI.MaskedValueIsZero(N0.getOperand(0), - ~N1C->getValue() & ((1ULL << InBits)-1))) { + ~N1C->getValue() & InMask)) { + SDOperand Zext = DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(), + N0.getOperand(0)); + + // Replace uses of the AND with uses of the Zero extend node. + CombineTo(N, Zext); + // We actually want to replace all uses of the any_extend with the // zero_extend, to avoid duplicating things. This will later cause this // AND to be folded. - CombineTo(N0.Val, DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(), - N0.getOperand(0))); + CombineTo(N0.Val, Zext); return SDOperand(); } } From alenhar2 at cs.uiuc.edu Wed Mar 1 15:51:28 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 1 Mar 2006 15:51:28 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2/channel.c Message-ID: <200603012151.PAA14349@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2: channel.c updated: 1.1 -> 1.2 --- Log message: u matches unsigned int not unsigned long, so fix this broken program --- Diffs of the changes: (+6 -2) channel.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2/channel.c diff -u llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2/channel.c:1.1 llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2/channel.c:1.2 --- llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2/channel.c:1.1 Tue Nov 5 12:51:11 2002 +++ llvm-test/MultiSource/Benchmarks/Ptrdist/yacr2/channel.c Wed Mar 1 15:51:15 2006 @@ -87,7 +87,9 @@ net = 0; do { line++; - stat = fscanf(channelFP, "%u%u%u", &col, &bot, &top); + unsigned int c1, b1, t1; + stat = fscanf(channelFP, "%u%u%u", &c1, &b1, &t1); + col = c1; bot = b1; top = t1; if (stat != EOF) { if (stat == 3) { /* @@ -203,7 +205,9 @@ line = 0; do { line++; - stat = fscanf(channelFP, "%u%u%u", &col, &bot, &top); + unsigned int c1, b1, t1; + stat = fscanf(channelFP, "%u%u%u", &c1, &b1, &t1); + col = c1; bot = b1; top = t1; if (stat != EOF) { if (stat == 3) { /* From evan.cheng at apple.com Wed Mar 1 16:01:11 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Mar 2006 16:01:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200603012201.QAA14457@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.194 -> 1.195 --- Log message: AsmWriter should not print LLVM constant in comment. Assembler won't like multi-line comments. --- Diffs of the changes: (+0 -4) AsmWriter.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.194 llvm/lib/VMCore/AsmWriter.cpp:1.195 --- llvm/lib/VMCore/AsmWriter.cpp:1.194 Mon Feb 27 04:33:53 2006 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Mar 1 16:00:59 2006 @@ -26,7 +26,6 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" -#include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" @@ -1312,9 +1311,6 @@ if (this == 0) { o << " constant value\n"; return; } o << ' ' << getType()->getDescription() << ' '; - - std::map TypeTable; - WriteConstantInt(o, this, false, TypeTable, 0); } void Type::print(std::ostream &o) const { From evan.cheng at apple.com Wed Mar 1 16:17:11 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Mar 2006 16:17:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200603012217.QAA14609@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.195 -> 1.196 --- Log message: Back out my last check-in. Wrong place to fix it. --- Diffs of the changes: (+3 -0) AsmWriter.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.195 llvm/lib/VMCore/AsmWriter.cpp:1.196 --- llvm/lib/VMCore/AsmWriter.cpp:1.195 Wed Mar 1 16:00:59 2006 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Mar 1 16:17:00 2006 @@ -1311,6 +1311,9 @@ if (this == 0) { o << " constant value\n"; return; } o << ' ' << getType()->getDescription() << ' '; + + std::map TypeTable; + WriteConstantInt(o, this, false, TypeTable, 0); } void Type::print(std::ostream &o) const { From evan.cheng at apple.com Wed Mar 1 16:18:21 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Mar 2006 16:18:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200603012218.QAA14631@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.55 -> 1.56 --- Log message: Don't print llvm constant in assmebly file. Assembler won't like comments that span multiple lines. --- Diffs of the changes: (+3 -1) AsmPrinter.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.55 llvm/lib/CodeGen/AsmPrinter.cpp:1.56 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.55 Fri Feb 24 14:21:58 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Wed Mar 1 16:18:09 2006 @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Assembly/Writer.h" #include "llvm/DerivedTypes.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Constants.h" @@ -114,7 +115,8 @@ EmitAlignment(MCP->getConstantPoolAlignment()); for (unsigned i = 0, e = CP.size(); i != e; ++i) { O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' << i - << ":\t\t\t\t\t" << CommentString << *CP[i].Val << '\n'; + << ":\t\t\t\t\t" << CommentString << " "; + WriteTypeSymbolic(O, CP[i].Val->getType(), 0) << '\n'; EmitGlobalConstant(CP[i].Val); if (i != e-1) { unsigned EntSize = TM.getTargetData().getTypeSize(CP[i].Val->getType()); From alenhar2 at cs.uiuc.edu Wed Mar 1 16:20:42 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 1 Mar 2006 16:20:42 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c Message-ID: <200603012220.QAA14664@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Ptrdist/anagram: anagram.c updated: 1.2 -> 1.3 --- Log message: you would almost think this was what sizeof was for, wouldn't you --- Diffs of the changes: (+1 -1) anagram.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c diff -u llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c:1.2 llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c:1.3 --- llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c:1.2 Wed Nov 10 02:43:01 2004 +++ llvm-test/MultiSource/Benchmarks/Ptrdist/anagram/anagram.c Wed Mar 1 16:20:30 2006 @@ -147,7 +147,7 @@ */ typedef unsigned long Quad; /* for building our bit mask */ -#define MASK_BITS 32 /* number of bits in a Quad */ +#define MASK_BITS (sizeof(Quad)*8) /* number of bits in a Quad */ #define MAX_QUADS 2 /* controls largest phrase */ From lattner at cs.uiuc.edu Wed Mar 1 16:45:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 16:45:24 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/2006-03-01-GimplifyCrash.cpp Message-ID: <200603012245.QAA15073@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: 2006-03-01-GimplifyCrash.cpp added (r1.1) --- Log message: testcase that crashed the new CFE --- Diffs of the changes: (+14 -0) 2006-03-01-GimplifyCrash.cpp | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/test/Regression/C++Frontend/2006-03-01-GimplifyCrash.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/2006-03-01-GimplifyCrash.cpp:1.1 *** /dev/null Wed Mar 1 16:45:22 2006 --- llvm/test/Regression/C++Frontend/2006-03-01-GimplifyCrash.cpp Wed Mar 1 16:45:12 2006 *************** *** 0 **** --- 1,14 ---- + // RUN: %llvmgxx -S %s -o - + + struct PrefMapElem { + virtual ~PrefMapElem(); + unsigned int fPrefId; + }; + + int foo() { + PrefMapElem* fMap; + if (fMap[0].fPrefId == 1) + return 1; + + return 0; + } From jlaskey at apple.com Wed Mar 1 17:52:51 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 17:52:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200603012352.RAA15799@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.39 -> 1.40 MachineDebugInfo.cpp updated: 1.21 -> 1.22 --- Log message: Support for enumerations. --- Diffs of the changes: (+57 -2) DwarfWriter.cpp | 15 +++++++++++++-- MachineDebugInfo.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.39 llvm/lib/CodeGen/DwarfWriter.cpp:1.40 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.39 Wed Mar 1 14:39:35 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Mar 1 17:52:37 2006 @@ -1109,8 +1109,8 @@ if (Lo != Hi) { Subrange->AddDIEntry(DW_AT_type, DW_FORM_ref4, IndexTy); // Only add low if non-zero. - if (Lo) Subrange->AddUInt(DW_AT_lower_bound, 0, Lo); - Subrange->AddUInt(DW_AT_upper_bound, 0, Hi); + if (Lo) Subrange->AddSInt(DW_AT_lower_bound, 0, Lo); + Subrange->AddSInt(DW_AT_upper_bound, 0, Hi); } Ty->AddChild(Subrange); } @@ -1124,6 +1124,17 @@ break; } case DW_TAG_enumeration_type: { + // Add enumerators to enumeration type. + for(unsigned i = 0, N = Elements.size(); i < N; ++i) { + EnumeratorDesc *ED = cast(Elements[i]); + const std::string &Name = ED->getName(); + int64_t Value = ED->getValue(); + DIE *Enumerator = new DIE(DW_TAG_enumerator); + Enumerator->AddString(DW_AT_name, DW_FORM_string, Name); + Enumerator->AddSInt(DW_AT_const_value, DW_FORM_sdata, Value); + Ty->AddChild(Enumerator); + } + break; } default: break; Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.21 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.22 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.21 Wed Mar 1 14:39:36 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Mar 1 17:52:37 2006 @@ -516,6 +516,7 @@ case DW_TAG_union_type: case DW_TAG_enumeration_type: return new CompositeTypeDesc(Tag); case DW_TAG_subrange_type: return new SubrangeDesc(); + case DW_TAG_enumerator: return new EnumeratorDesc(); default: break; } return NULL; @@ -909,6 +910,49 @@ //===----------------------------------------------------------------------===// +EnumeratorDesc::EnumeratorDesc() +: DebugInfoDesc(DW_TAG_enumerator) +, Name("") +, Value(0) +{} + +// Implement isa/cast/dyncast. +bool EnumeratorDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_enumerator; +} + +/// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. +/// +void EnumeratorDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Name); + Visitor->Apply(Value); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *EnumeratorDesc::getDescString() const { + return "llvm.dbg.enumerator"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *EnumeratorDesc::getTypeString() const { + return "llvm.dbg.enumerator.type"; +} + +#ifndef NDEBUG +void EnumeratorDesc::dump() { + std::cerr << getDescString() << " " + << "Tag(" << getTag() << "), " + << "Name(" << Name << "), " + << "Value(" << Value << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + GlobalDesc::GlobalDesc(unsigned T) : AnchoredDesc(T) , Context(0) From jlaskey at apple.com Wed Mar 1 17:52:51 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 1 Mar 2006 17:52:51 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603012352.RAA15803@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.25 -> 1.26 --- Log message: Support for enumerations. --- Diffs of the changes: (+38 -0) MachineDebugInfo.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.25 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.26 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.25 Wed Mar 1 14:49:44 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Mar 1 17:52:37 2006 @@ -447,6 +447,44 @@ }; //===----------------------------------------------------------------------===// +/// EnumeratorDesc - This class packages debug information associated with +/// named integer constants. +class EnumeratorDesc : public DebugInfoDesc { +private: + std::string Name; // Enumerator name. + int64_t Value; // Enumerator value. + +public: + EnumeratorDesc(); + + // Accessors + const std::string &getName() const { return Name; } + int64_t getValue() const { return Value; } + void setName(const std::string &N) { Name = N; } + void setValue(int64_t V) { Value = V; } + + // Implement isa/cast/dyncast. + static bool classof(const EnumeratorDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// /// GlobalDesc - This class is the base descriptor for global functions and /// variables. class GlobalDesc : public AnchoredDesc { From lattner at cs.uiuc.edu Wed Mar 1 18:21:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Mar 2006 18:21:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h Message-ID: <200603020021.SAA16022@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.28 -> 1.29 --- Log message: Fix a compilation error with GCC 4.1. Thanks to Vladimir Merzliakov for pointing this out. --- Diffs of the changes: (+1 -1) DwarfWriter.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.28 llvm/include/llvm/CodeGen/DwarfWriter.h:1.29 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.28 Wed Mar 1 12:20:30 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Wed Mar 1 18:21:41 2006 @@ -302,7 +302,7 @@ /// NewType - Create a new type DIE. /// - DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc); + DIE *NewType(DIE *Context, TypeDesc *TyDesc); /// NewCompileUnit - Create new compile unit and it's die. /// From lattner at cs.uiuc.edu Thu Mar 2 00:50:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 00:50:16 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/rem.ll Message-ID: <200603020650.AAA18095@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: rem.ll updated: 1.11 -> 1.12 --- Log message: add a couple more cases --- Diffs of the changes: (+17 -0) rem.ll | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/rem.ll diff -u llvm/test/Regression/Transforms/InstCombine/rem.ll:1.11 llvm/test/Regression/Transforms/InstCombine/rem.ll:1.12 --- llvm/test/Regression/Transforms/InstCombine/rem.ll:1.11 Mon Feb 27 23:48:56 2006 +++ llvm/test/Regression/Transforms/InstCombine/rem.ll Thu Mar 2 00:50:04 2006 @@ -60,3 +60,20 @@ %C = rem uint %B, 62 ret uint %C } + +int %test10(ubyte %c) { + %tmp.1 = cast ubyte %c to int + %tmp.2 = mul int %tmp.1, 3 + %tmp.3 = cast int %tmp.2 to ulong + %tmp.5 = rem ulong %tmp.3, 3 + %tmp.6 = cast ulong %tmp.5 to int + ret int %tmp.6 +} + +int %test11(int %i) { + %tmp.1 = and int %i, -2 + %tmp.3 = mul int %tmp.1, 3 + %tmp.5 = rem int %tmp.3, 6 + ret int %tmp.5 +} + From lattner at cs.uiuc.edu Thu Mar 2 00:51:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 00:51:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200603020651.AAA18131@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.445 -> 1.446 --- Log message: Generalize the REM folding code to handle another case Nick Lewycky pointed out: realize the AND can provide factors and look through Casts. --- Diffs of the changes: (+43 -13) InstructionCombining.cpp | 56 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 43 insertions(+), 13 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.445 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.446 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.445 Tue Feb 28 13:47:20 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Mar 2 00:50:58 2006 @@ -1812,6 +1812,45 @@ } +/// GetFactor - If we can prove that the specified value is at least a multiple +/// of some factor, return that factor. +static Constant *GetFactor(Value *V) { + if (ConstantInt *CI = dyn_cast(V)) + return CI; + + // Unless we can be tricky, we know this is a multiple of 1. + Constant *Result = ConstantInt::get(V->getType(), 1); + + Instruction *I = dyn_cast(V); + if (!I) return Result; + + if (I->getOpcode() == Instruction::Mul) { + // Handle multiplies by a constant, etc. + return ConstantExpr::getMul(GetFactor(I->getOperand(0)), + GetFactor(I->getOperand(1))); + } else if (I->getOpcode() == Instruction::Shl) { + // (X< X * (1 << C) + if (Constant *ShRHS = dyn_cast(I->getOperand(1))) { + ShRHS = ConstantExpr::getShl(Result, ShRHS); + return ConstantExpr::getMul(GetFactor(I->getOperand(0)), ShRHS); + } + } else if (I->getOpcode() == Instruction::And) { + if (ConstantInt *RHS = dyn_cast(I->getOperand(1))) { + // X & 0xFFF0 is known to be a multiple of 16. + unsigned Zeros = CountTrailingZeros_64(RHS->getZExtValue()); + if (Zeros != V->getType()->getPrimitiveSizeInBits()) + return ConstantExpr::getShl(Result, + ConstantUInt::get(Type::UByteTy, Zeros)); + } + } else if (I->getOpcode() == Instruction::Cast) { + Value *Op = I->getOperand(0); + // Only handle int->int casts. + if (!Op->getType()->isInteger()) return Result; + return ConstantExpr::getCast(GetFactor(Op), V->getType()); + } + return Result; +} + Instruction *InstCombiner::visitRem(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -1874,20 +1913,11 @@ } else if (isa(Op0I)) { if (Instruction *NV = FoldOpIntoPhi(I)) return NV; - } else if (Op0I->getOpcode() == Instruction::Mul) { - // X*C1%C2 --> 0 iff C1%C2 == 0 - if (ConstantInt *MulRHS = dyn_cast(Op0I->getOperand(1))) { - if (ConstantExpr::getRem(MulRHS, RHS)->isNullValue()) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - } - } else if (Op0I->getOpcode() == Instruction::Shl) { - // (X< 0 iff (1<(Op0I->getOperand(1))) { - ShRHS = ConstantExpr::getShl(ConstantInt::get(I.getType(), 1), ShRHS); - if (ConstantExpr::getRem(ShRHS, RHS)->isNullValue()) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - } } + + // X*C1%C2 --> 0 iff C1%C2 == 0 + if (ConstantExpr::getRem(GetFactor(Op0I), RHS)->isNullValue()) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); } } From evan.cheng at apple.com Thu Mar 2 15:38:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 2 Mar 2006 15:38:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603022138.PAA00817@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.6 -> 1.7 --- Log message: - Fixed some priority calculation bugs that were causing bug 478: http://llvm.cs.uiuc.edu/PR478 . Among them: a predecessor appearing more than once in the operand list was counted as multiple predecessor; priority1 should be updated during scheduling; CycleBound was updated after the node is inserted into priority queue; one of the tie breaking condition was flipped. - Take into consideration of two address opcodes. If a predecessor is a def&use operand, it should have a higher priority. - Scheduler should also favor floaters, i.e. nodes that do not have real predecessors such as MOV32ri. - The scheduling fixes / tweaks fixed bug 478: http://llvm.cs.uiuc.edu/PR478 : .text .align 4 .globl _f _f: movl 4(%esp), %eax movl 8(%esp), %ecx movl %eax, %edx imull %ecx, %edx imull %eax, %eax imull %ecx, %ecx addl %eax, %ecx leal (%ecx,%edx,2), %eax ret It is also a slight performance win (1% - 3%) for most tests. --- Diffs of the changes: (+98 -64) ScheduleDAGList.cpp | 162 +++++++++++++++++++++++++++++++--------------------- 1 files changed, 98 insertions(+), 64 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.6 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.7 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.6 Wed Feb 1 18:38:08 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 2 15:38:29 2006 @@ -21,8 +21,9 @@ #include "llvm/Support/Debug.h" #include #include -#include #include +#include +#include using namespace llvm; namespace { @@ -32,14 +33,17 @@ struct SUnit { SDNode *Node; // Representative node. std::vector FlaggedNodes; // All nodes flagged to Node. - std::vector Preds; // All real predecessors. - std::vector ChainPreds; // All chain predecessors. - std::vector Succs; // All real successors. - std::vector ChainSuccs; // All chain successors. + std::set Preds; // All real predecessors. + std::set ChainPreds; // All chain predecessors. + std::set Succs; // All real successors. + std::set ChainSuccs; // All chain successors. int NumPredsLeft; // # of preds not scheduled. int NumSuccsLeft; // # of succs not scheduled. + int NumChainPredsLeft; // # of chain preds not scheduled. + int NumChainSuccsLeft; // # of chain succs not scheduled. int Priority1; // Scheduling priority 1. int Priority2; // Scheduling priority 2. + bool isDefNUseOperand; // Is a def&use operand. unsigned Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. unsigned Slot; // Cycle node is scheduled at. @@ -47,8 +51,9 @@ SUnit(SDNode *node) : Node(node), NumPredsLeft(0), NumSuccsLeft(0), - Priority1(INT_MIN), Priority2(INT_MIN), Latency(0), - CycleBound(0), Slot(0), Next(NULL) {} + NumChainPredsLeft(0), NumChainSuccsLeft(0), + Priority1(INT_MIN), Priority2(INT_MIN), isDefNUseOperand(false), + Latency(0), CycleBound(0), Slot(0), Next(NULL) {} void dump(const SelectionDAG *G, bool All=true) const; }; @@ -66,37 +71,43 @@ } if (All) { - std::cerr << "# preds left : " << NumPredsLeft << "\n"; - std::cerr << "# succs left : " << NumSuccsLeft << "\n"; - std::cerr << "Latency : " << Latency << "\n"; - std::cerr << "Priority : " << Priority1 << " , " << Priority2 << "\n"; + std::cerr << "# preds left : " << NumPredsLeft << "\n"; + std::cerr << "# succs left : " << NumSuccsLeft << "\n"; + std::cerr << "# chain preds left : " << NumChainPredsLeft << "\n"; + std::cerr << "# chain succs left : " << NumChainSuccsLeft << "\n"; + std::cerr << "Latency : " << Latency << "\n"; + std::cerr << "Priority : " << Priority1 << " , " << Priority2 << "\n"; if (Preds.size() != 0) { std::cerr << "Predecessors :\n"; - for (unsigned i = 0, e = Preds.size(); i != e; i++) { + for (std::set::iterator I = Preds.begin(), + E = Preds.end(); I != E; ++I) { std::cerr << " "; - Preds[i]->dump(G, false); + (*I)->dump(G, false); } } if (ChainPreds.size() != 0) { std::cerr << "Chained Preds :\n"; - for (unsigned i = 0, e = ChainPreds.size(); i != e; i++) { + for (std::set::iterator I = ChainPreds.begin(), + E = ChainPreds.end(); I != E; ++I) { std::cerr << " "; - ChainPreds[i]->dump(G, false); + (*I)->dump(G, false); } } if (Succs.size() != 0) { std::cerr << "Successors :\n"; - for (unsigned i = 0, e = Succs.size(); i != e; i++) { + for (std::set::iterator I = Succs.begin(), + E = Succs.end(); I != E; ++I) { std::cerr << " "; - Succs[i]->dump(G, false); + (*I)->dump(G, false); } } if (ChainSuccs.size() != 0) { std::cerr << "Chained succs :\n"; - for (unsigned i = 0, e = ChainSuccs.size(); i != e; i++) { + for (std::set::iterator I = ChainSuccs.begin(), + E = ChainSuccs.end(); I != E; ++I) { std::cerr << " "; - ChainSuccs[i]->dump(G, false); + (*I)->dump(G, false); } } } @@ -105,24 +116,30 @@ /// Sorting functions for the Available queue. struct ls_rr_sort : public std::binary_function { bool operator()(const SUnit* left, const SUnit* right) const { - if (left->Priority1 > right->Priority1) { + bool LFloater = (left ->Preds.size() == 0); + bool RFloater = (right->Preds.size() == 0); + int LBonus = (int)left ->isDefNUseOperand; + int RBonus = (int)right->isDefNUseOperand; + int LPriority1 = left ->Priority1 - LBonus; + int RPriority1 = right->Priority1 - RBonus; + int LPriority2 = left ->Priority2 + LBonus; + int RPriority2 = right->Priority2 + RBonus; + + // Favor floaters (i.e. node with no non-passive predecessors): + // e.g. MOV32ri. + if (!LFloater && RFloater) return true; - } else if (left->Priority1 == right->Priority1) { - unsigned lf = left->FlaggedNodes.size(); - unsigned rf = right->FlaggedNodes.size(); - if (lf > rf) + else if (LFloater == RFloater) + if (LPriority1 > RPriority1) return true; - else if (lf == rf) { - if (left->Priority2 > right->Priority2) + else if (LPriority1 == RPriority1) + if (LPriority2 < RPriority2) return true; - else if (left->Priority2 == right->Priority2) { + else if (LPriority1 == RPriority1) if (left->CycleBound > right->CycleBound) return true; else return left->Node->getNodeDepth() < right->Node->getNodeDepth(); - } - } - } return false; } @@ -163,7 +180,7 @@ private: SUnit *NewSUnit(SDNode *N); - void ReleasePred(SUnit *PredSU); + void ReleasePred(SUnit *PredSU, bool isChain = false); void ScheduleNode(SUnit *SU); int CalcNodePriority(SUnit *SU); void CalculatePriorities(); @@ -189,11 +206,21 @@ /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to /// the Available queue is the count reaches zero. Also update its cycle bound. -void ScheduleDAGList::ReleasePred(SUnit *PredSU) { +void ScheduleDAGList::ReleasePred(SUnit *PredSU, bool isChain) { SDNode *PredNode = PredSU->Node; - PredSU->NumSuccsLeft--; - if (PredSU->NumSuccsLeft == 0) { + // FIXME: the distance between two nodes is not always == the predecessor's + // latency. For example, the reader can very well read the register written + // by the predecessor later than the issue cycle. It also depends on the + // interrupt model (drain vs. freeze). + PredSU->CycleBound = std::max(PredSU->CycleBound, CurrCycle + PredSU->Latency); + + if (!isChain) { + PredSU->NumSuccsLeft--; + PredSU->Priority1++; + } else + PredSU->NumChainSuccsLeft--; + if (PredSU->NumSuccsLeft == 0 && PredSU->NumChainSuccsLeft == 0) { // EntryToken has to go last! if (PredNode->getOpcode() != ISD::EntryToken) Available.push(PredSU); @@ -205,12 +232,6 @@ assert(0); #endif } - - // FIXME: the distance between two nodes is not always == the predecessor's - // latency. For example, the reader can very well read the register written - // by the predecessor later than the issue cycle. It also depends on the - // interrupt model (drain vs. freeze). - PredSU->CycleBound = std::max(PredSU->CycleBound, CurrCycle + PredSU->Latency); } /// ScheduleNode - Add the node to the schedule. Decrement the pending count of @@ -221,10 +242,15 @@ SU->Slot = CurrCycle; // Bottom up: release predecessors - for (unsigned i = 0, e = SU->Preds.size(); i != e; i++) - ReleasePred(SU->Preds[i]); - for (unsigned i = 0, e = SU->ChainPreds.size(); i != e; i++) - ReleasePred(SU->ChainPreds[i]); + for (std::set::iterator I1 = SU->Preds.begin(), + E1 = SU->Preds.end(); I1 != E1; ++I1) { + ReleasePred(*I1); + SU->NumPredsLeft--; + SU->Priority1--; + } + for (std::set::iterator I2 = SU->ChainPreds.begin(), + E2 = SU->ChainPreds.end(); I2 != E2; ++I2) + ReleasePred(*I2, true); CurrCycle++; } @@ -272,7 +298,7 @@ #ifndef NDEBUG bool AnyNotSched = false; for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { - if (SU->NumSuccsLeft != 0) { + if (SU->NumSuccsLeft != 0 || SU->NumChainSuccsLeft != 0) { if (!AnyNotSched) std::cerr << "*** List scheduling failed! ***\n"; SU->dump(&DAG); @@ -292,22 +318,24 @@ DEBUG(std::cerr << "\n"); } -/// CalcNodePriority - Priority 1 is just the number of live range genned - number -/// of live range killed. Priority 2 is the Sethi Ullman number. It returns -/// priority 2 since it is calculated recursively. -/// Smaller number is the higher priority in both cases. +/// CalcNodePriority - Priority1 is just the number of live range genned - +/// number of live range killed. Priority2 is the Sethi Ullman number. It +/// returns Priority2 since it is calculated recursively. +/// Smaller number is the higher priority for Priority2. Reverse is true for +/// Priority1. int ScheduleDAGList::CalcNodePriority(SUnit *SU) { if (SU->Priority2 != INT_MIN) return SU->Priority2; - SU->Priority1 = SU->Preds.size() - SU->Succs.size(); + SU->Priority1 = SU->NumPredsLeft - SU->NumSuccsLeft; if (SU->Preds.size() == 0) { SU->Priority2 = 1; } else { int Extra = 0; - for (unsigned i = 0, e = SU->Preds.size(); i != e; i++) { - SUnit *PredSU = SU->Preds[i]; + for (std::set::iterator I = SU->Preds.begin(), + E = SU->Preds.end(); I != E; ++I) { + SUnit *PredSU = *I; int PredPriority = CalcNodePriority(PredSU); if (PredPriority > SU->Priority2) { SU->Priority2 = PredPriority; @@ -387,14 +415,16 @@ assert(VT != MVT::Flag); SUnit *OpSU = SUnitMap[OpN]; if (VT == MVT::Other) { - SU ->ChainPreds.push_back(OpSU); - OpSU->ChainSuccs.push_back(SU); + if (SU->ChainPreds.insert(OpSU).second) + SU->NumChainPredsLeft++; + if (OpSU->ChainSuccs.insert(SU).second) + OpSU->NumChainSuccsLeft++; } else { - SU ->Preds.push_back(OpSU); - OpSU->Succs.push_back(SU); + if (SU->Preds.insert(OpSU).second) + SU->NumPredsLeft++; + if (OpSU->Succs.insert(SU).second) + OpSU->NumSuccsLeft++; } - SU->NumPredsLeft++; - OpSU->NumSuccsLeft++; } } } else { @@ -407,14 +437,18 @@ assert(VT != MVT::Flag); SUnit *OpSU = SUnitMap[OpN]; if (VT == MVT::Other) { - SU ->ChainPreds.push_back(OpSU); - OpSU->ChainSuccs.push_back(SU); + if (SU->ChainPreds.insert(OpSU).second) + SU->NumChainPredsLeft++; + if (OpSU->ChainSuccs.insert(SU).second) + OpSU->NumChainSuccsLeft++; } else { - SU ->Preds.push_back(OpSU); - OpSU->Succs.push_back(SU); + if (SU->Preds.insert(OpSU).second) + SU->NumPredsLeft++; + if (OpSU->Succs.insert(SU).second) + OpSU->NumSuccsLeft++; + if (j == 0 && TII->isTwoAddrInstr(N->getTargetOpcode())) + OpSU->isDefNUseOperand = true; } - SU->NumPredsLeft++; - OpSU->NumSuccsLeft++; } } } From evan.cheng at apple.com Thu Mar 2 15:48:46 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 2 Mar 2006 15:48:46 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-03-01-InstrSchedBug.ll Message-ID: <200603022148.PAA00872@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-03-01-InstrSchedBug.ll added (r1.1) --- Log message: Add a regression test for bug 478: http://llvm.cs.uiuc.edu/PR478 . --- Diffs of the changes: (+11 -0) 2006-03-01-InstrSchedBug.ll | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-03-01-InstrSchedBug.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-03-01-InstrSchedBug.ll:1.1 *** /dev/null Thu Mar 2 15:48:44 2006 --- llvm/test/Regression/CodeGen/X86/2006-03-01-InstrSchedBug.ll Thu Mar 2 15:48:34 2006 *************** *** 0 **** --- 1,11 ---- + ; RUN: llvm-as < %s | llc -march=x86 | not grep 'subl.*%esp' + + int %f(int %a, int %b) { + %tmp.2 = mul int %a, %a + %tmp.5 = shl int %a, ubyte 1 + %tmp.6 = mul int %tmp.5, %b + %tmp.10 = mul int %b, %b + %tmp.7 = add int %tmp.10, %tmp.2 + %tmp.11 = add int %tmp.7, %tmp.6 + ret int %tmp.11 + } From lattner at cs.uiuc.edu Thu Mar 2 16:34:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 16:34:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603022234.QAA01337@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.8 -> 1.9 --- Log message: add a note --- Diffs of the changes: (+7 -0) README.txt | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.8 llvm/lib/Target/README.txt:1.9 --- llvm/lib/Target/README.txt:1.8 Tue Feb 21 12:29:44 2006 +++ llvm/lib/Target/README.txt Thu Mar 2 16:34:38 2006 @@ -79,3 +79,10 @@ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25600 http://gcc.gnu.org/ml/gcc-patches/2006-02/msg01492.html +//===---------------------------------------------------------------------===// + +We should reassociate: +int f(int a, int b){ return a * a + 2 * a * b + b * b; } +into: +int f(int a, int b) { return a * (a + 2 * b) + b * b; } +to eliminate a multiply. From lattner at cs.uiuc.edu Thu Mar 2 17:56:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 17:56:35 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Bytecode/memcpy.ll memcpy.ll.bc-16 Message-ID: <200603022356.RAA02151@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Bytecode: memcpy.ll added (r1.1) memcpy.ll.bc-16 added (r1.1) --- Log message: new testcases --- Diffs of the changes: (+21 -0) memcpy.ll | 21 +++++++++++++++++++++ memcpy.ll.bc-16 | 0 2 files changed, 21 insertions(+) Index: llvm/test/Regression/Bytecode/memcpy.ll diff -c /dev/null llvm/test/Regression/Bytecode/memcpy.ll:1.1 *** /dev/null Thu Mar 2 17:56:33 2006 --- llvm/test/Regression/Bytecode/memcpy.ll Thu Mar 2 17:56:23 2006 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-dis %s.bc-16 -o /dev/null -f && + ; RUN: llc %s.bc-16 -o /dev/null -f -march=c && + ; RUN: llvm-as < %s + + void %test(int* %P, int* %Q) { + entry: + %tmp.1 = cast int* %P to sbyte* ; [#uses=2] + %tmp.3 = cast int* %Q to sbyte* ; [#uses=3] + tail call void %llvm.memcpy( sbyte* %tmp.1, sbyte* %tmp.3, uint 100000, uint 1 ) + tail call void %llvm.memcpy( sbyte* %tmp.1, sbyte* %tmp.3, ulong 100000, uint 1 ) + tail call void %llvm.memset( sbyte* %tmp.3, ubyte 14, uint 10000, uint 0 ) + tail call void %llvm.memmove( sbyte* %tmp.1, sbyte* %tmp.3, uint 123124, uint 1 ) + ret void + } + + declare void %llvm.memcpy(sbyte*, sbyte*, uint, uint) + declare void %llvm.memcpy(sbyte*, sbyte*, ulong, uint) + + declare void %llvm.memset(sbyte*, ubyte, uint, uint) + + declare void %llvm.memmove(sbyte*, sbyte*, uint, uint) Index: llvm/test/Regression/Bytecode/memcpy.ll.bc-16 From lattner at cs.uiuc.edu Thu Mar 2 17:57:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 17:57:30 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Assembly/AutoUpgrade.h Message-ID: <200603022357.RAA02226@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Assembly: AutoUpgrade.h updated: 1.4 -> 1.5 --- Log message: Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving PR709: http://llvm.cs.uiuc.edu/PR709 , and paving the way for future progress. --- Diffs of the changes: (+2 -12) AutoUpgrade.h | 14 ++------------ 1 files changed, 2 insertions(+), 12 deletions(-) Index: llvm/include/llvm/Assembly/AutoUpgrade.h diff -u llvm/include/llvm/Assembly/AutoUpgrade.h:1.4 llvm/include/llvm/Assembly/AutoUpgrade.h:1.5 --- llvm/include/llvm/Assembly/AutoUpgrade.h:1.4 Fri Jan 27 05:49:27 2006 +++ llvm/include/llvm/Assembly/AutoUpgrade.h Thu Mar 2 17:57:16 2006 @@ -24,12 +24,6 @@ class Value; class BasicBlock; - /// This function determines if the \p Name provides is a name for which the - /// auto-upgrade to a non-overloaded name applies. - /// @returns True if the function name is upgradeable, false otherwise. - /// @brief Determine if a name is an upgradeable intrinsic name. - bool IsUpgradeableIntrinsicName(const std::string& Name); - /// This function inspects the Function \p F to see if it is an old overloaded /// intrinsic. If it is, the Function's name is changed to add a suffix that /// indicates the kind of arguments or result that it accepts. In LLVM release @@ -56,14 +50,10 @@ /// non-overloaded names. This function inspects the CallInst \p CI to see /// if it is a call to an old overloaded intrinsic. If it is, a new CallInst /// is created that uses the correct Function and possibly casts the - /// argument and result to an unsigned type. The caller can use the - /// returned Instruction to replace the existing one. Note that the - /// Instruction* returned could be a CallInst or a CastInst depending on - /// whether casting was necessary. + /// argument and result to an unsigned type. /// @param CI The CallInst to potentially auto-upgrade. - /// @returns An instrution to replace \p CI with. /// @brief Get replacement instruction for overloaded intrinsic function call. - Instruction* UpgradeIntrinsicCall(CallInst* CI, Function* newF = 0); + void UpgradeIntrinsicCall(CallInst* CI, Function* newF = 0); /// Upgrade both the function and all the calls made to it, if that function /// needs to be upgraded. This is like a combination of the above two From lattner at cs.uiuc.edu Thu Mar 2 17:57:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 17:57:30 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicInst.h Intrinsics.h Message-ID: <200603022357.RAA02222@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicInst.h updated: 1.9 -> 1.10 Intrinsics.h updated: 1.36 -> 1.37 --- Log message: Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving PR709: http://llvm.cs.uiuc.edu/PR709 , and paving the way for future progress. --- Diffs of the changes: (+23 -14) IntrinsicInst.h | 20 +++++++++++++------- Intrinsics.h | 17 ++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) Index: llvm/include/llvm/IntrinsicInst.h diff -u llvm/include/llvm/IntrinsicInst.h:1.9 llvm/include/llvm/IntrinsicInst.h:1.10 --- llvm/include/llvm/IntrinsicInst.h:1.9 Fri Jan 13 14:00:51 2006 +++ llvm/include/llvm/IntrinsicInst.h Thu Mar 2 17:57:16 2006 @@ -148,9 +148,12 @@ static inline bool classof(const MemIntrinsic *) { return true; } static inline bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { - case Intrinsic::memcpy: - case Intrinsic::memmove: - case Intrinsic::memset: + case Intrinsic::memcpy_i32: + case Intrinsic::memcpy_i64: + case Intrinsic::memmove_i32: + case Intrinsic::memmove_i64: + case Intrinsic::memset_i32: + case Intrinsic::memset_i64: return true; default: return false; } @@ -183,7 +186,8 @@ // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemCpyInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::memcpy; + return I->getIntrinsicID() == Intrinsic::memcpy_i32 || + I->getIntrinsicID() == Intrinsic::memcpy_i64; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -211,14 +215,15 @@ // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemMoveInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::memmove; + return I->getIntrinsicID() == Intrinsic::memmove_i32 || + I->getIntrinsicID() == Intrinsic::memmove_i64; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; - /// MemSetInst - This class wraps the llvm.memcpy intrinsic. + /// MemSetInst - This class wraps the llvm.memset intrinsic. /// struct MemSetInst : public MemIntrinsic { /// get* - Return the arguments to the instruction. @@ -234,7 +239,8 @@ // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemSetInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::memset; + return I->getIntrinsicID() == Intrinsic::memset_i32 || + I->getIntrinsicID() == Intrinsic::memset_i64; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.36 llvm/include/llvm/Intrinsics.h:1.37 --- llvm/include/llvm/Intrinsics.h:1.36 Mon Jan 16 15:12:35 2006 +++ llvm/include/llvm/Intrinsics.h Thu Mar 2 17:57:16 2006 @@ -59,13 +59,16 @@ dbg_declare, // Declare a local object // Standard C library intrinsics. - memcpy, // Copy non-overlapping memory blocks - memmove, // Copy potentially overlapping memory blocks - memset, // Fill memory with a byte value - isunordered_f32,// Return true if either float argument is a NaN - isunordered_f64,// Return true if either double argument is a NaN - sqrt_f32, // Square root of float - sqrt_f64, // Square root of double + memcpy_i32, // Copy non-overlapping memory blocks. i32 size. + memcpy_i64, // Copy non-overlapping memory blocks. i64 size. + memmove_i32, // Copy potentially overlapping memory blocks. i32 size. + memmove_i64, // Copy potentially overlapping memory blocks. i64 size. + memset_i32, // Fill memory with a byte value. i32 size. + memset_i64, // Fill memory with a byte value. i64 size. + isunordered_f32, // Return true if either float argument is a NaN + isunordered_f64, // Return true if either double argument is a NaN + sqrt_f32, // Square root of float + sqrt_f64, // Square root of double // Bit manipulation instrinsics. bswap_i16, // Byteswap 16 bits From lattner at cs.uiuc.edu Thu Mar 2 17:58:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 17:58:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AutoUpgrade.cpp Function.cpp Verifier.cpp Message-ID: <200603022358.RAA02297@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AutoUpgrade.cpp updated: 1.8 -> 1.9 Function.cpp updated: 1.100 -> 1.101 Verifier.cpp updated: 1.146 -> 1.147 --- Log message: Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving PR709: http://llvm.cs.uiuc.edu/PR709 , and paving the way for future progress. Significantly refactor autoupgrading code, to handle the more complex case (where we upgrade one argument in a function), and fix some bugs in it. Testcase here: llvm/test/Regression/Bytecode/memcpy.ll --- Diffs of the changes: (+128 -139) AutoUpgrade.cpp | 249 ++++++++++++++++++++++++++------------------------------ Function.cpp | 9 +- Verifier.cpp | 9 +- 3 files changed, 128 insertions(+), 139 deletions(-) Index: llvm/lib/VMCore/AutoUpgrade.cpp diff -u llvm/lib/VMCore/AutoUpgrade.cpp:1.8 llvm/lib/VMCore/AutoUpgrade.cpp:1.9 --- llvm/lib/VMCore/AutoUpgrade.cpp:1.8 Fri Jan 27 05:49:27 2006 +++ llvm/lib/VMCore/AutoUpgrade.cpp Thu Mar 2 17:58:40 2006 @@ -23,54 +23,86 @@ using namespace llvm; // Utility function for getting the correct suffix given a type -static inline const char* get_suffix(const Type* Ty) { +static inline const char *getTypeSuffix(const Type* Ty) { switch (Ty->getTypeID()) { - case Type::UIntTyID: return ".i32"; - case Type::UShortTyID: return ".i16"; - case Type::UByteTyID: return ".i8"; - case Type::ULongTyID: return ".i64"; - case Type::FloatTyID: return ".f32"; - case Type::DoubleTyID: return ".f64"; - default: break; + case Type::ULongTyID: return ".i64"; + case Type::UIntTyID: return ".i32"; + case Type::UShortTyID: return ".i16"; + case Type::UByteTyID: return ".i8"; + case Type::FloatTyID: return ".f32"; + case Type::DoubleTyID: return ".f64"; + default: break; } return 0; } -static inline const Type* getTypeFromFunctionName(Function* F) { +static Function *getUpgradedUnaryFn(Function *F) { + std::string Name = F->getName()+getTypeSuffix(F->getReturnType()); + Module *M = F->getParent(); + switch (F->getReturnType()->getTypeID()) { + default: return 0; + case Type::UByteTyID: + case Type::SByteTyID: + return M->getOrInsertFunction(Name, + Type::UByteTy, Type::UByteTy, NULL); + case Type::UShortTyID: + case Type::ShortTyID: + return M->getOrInsertFunction(Name, + Type::UShortTy, Type::UShortTy, NULL); + case Type::UIntTyID: + case Type::IntTyID: + return M->getOrInsertFunction(Name, + Type::UIntTy, Type::UIntTy, NULL); + case Type::ULongTyID: + case Type::LongTyID: + return M->getOrInsertFunction(Name, + Type::ULongTy, Type::ULongTy, NULL); +} +} + +static Function *getUpgradedIntrinsic(Function *F) { // If there's no function, we can't get the argument type. - if (!F) - return 0; + if (!F) return 0; // Get the Function's name. const std::string& Name = F->getName(); // Quickly eliminate it, if it's not a candidate. - if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || Name[2] != - 'v' || Name[3] != 'm' || Name[4] != '.') + if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || + Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') return 0; + Module *M = F->getParent(); switch (Name[5]) { - case 'b': - if (Name == "llvm.bswap") - return F->getReturnType(); - break; - case 'c': - if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") - return F->getReturnType(); - break; - case 'i': - if (Name == "llvm.isunordered") { - Function::const_arg_iterator ArgIt = F->arg_begin(); - if (ArgIt != F->arg_end()) - return ArgIt->getType(); - } - break; - case 's': - if (Name == "llvm.sqrt") - return F->getReturnType(); - break; - default: - break; + default: break; + case 'b': + if (Name == "llvm.bswap") return getUpgradedUnaryFn(F); + break; + case 'c': + if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") + return getUpgradedUnaryFn(F); + break; + case 'i': + if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) { + if (F->arg_begin()->getType() == Type::FloatTy) + return M->getOrInsertFunction(Name+".f32", F->getFunctionType()); + if (F->arg_begin()->getType() == Type::DoubleTy) + return M->getOrInsertFunction(Name+".f64", F->getFunctionType()); + } + break; + case 'm': + if (Name == "llvm.memcpy" || Name == "llvm.memset" || + Name == "llvm.memmove") { + if (F->getFunctionType()->getParamType(2) == Type::UIntTy) + return M->getOrInsertFunction(Name+".i32", F->getFunctionType()); + if (F->getFunctionType()->getParamType(2) == Type::ULongTy) + return M->getOrInsertFunction(Name+".i64", F->getFunctionType()); + } + break; + case 's': + if (Name == "llvm.sqrt") + return getUpgradedUnaryFn(F); + break; } return 0; } @@ -92,75 +124,24 @@ return 0; } -bool llvm::IsUpgradeableIntrinsicName(const std::string& Name) { - // Quickly eliminate it, if it's not a candidate. - if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || Name[2] != - 'v' || Name[3] != 'm' || Name[4] != '.') - return false; - - switch (Name[5]) { - case 'b': - if (Name == "llvm.bswap") - return true; - break; - case 'c': - if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") - return true; - break; - case 'i': - if (Name == "llvm.isunordered") - return true; - break; - case 's': - if (Name == "llvm.sqrt") - return true; - break; - default: - break; - } - return false; -} - // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to // their non-overloaded variants by appending the appropriate suffix based on // the argument types. -Function* llvm::UpgradeIntrinsicFunction(Function* F) { +Function *llvm::UpgradeIntrinsicFunction(Function* F) { // See if its one of the name's we're interested in. - if (const Type* Ty = getTypeFromFunctionName(F)) { - const char* suffix = - get_suffix((Ty->isSigned() ? Ty->getUnsignedVersion() : Ty)); - assert(suffix && "Intrinsic parameter type not recognized"); - const std::string& Name = F->getName(); - std::string new_name = Name + suffix; - std::cerr << "WARNING: change " << Name << " to " << new_name << "\n"; - SymbolTable& SymTab = F->getParent()->getSymbolTable(); - if (Value* V = SymTab.lookup(F->getType(),new_name)) - if (Function* OtherF = dyn_cast(V)) - return OtherF; - - // There wasn't an existing function for the intrinsic, so now make sure the - // signedness of the arguments is correct. - if (Ty->isSigned()) { - const Type* newTy = Ty->getUnsignedVersion(); - std::vector Params; - Params.push_back(newTy); - FunctionType* FT = FunctionType::get(newTy, Params,false); - return new Function(FT, GlobalValue::ExternalLinkage, new_name, - F->getParent()); - } - - // The argument was the correct type (unsigned or floating), so just - // rename the function to its correct name and return it. - F->setName(new_name); - return F; + if (Function *R = getUpgradedIntrinsic(F)) { + std::cerr << "WARNING: change " << F->getName() << " to " + << R->getName() << "\n"; + return R; } return 0; } -Instruction* llvm::MakeUpgradedCall( - Function* F, const std::vector& Params, BasicBlock* BB, - bool isTailCall, unsigned CallingConv) { +Instruction* llvm::MakeUpgradedCall(Function *F, + const std::vector &Params, + BasicBlock *BB, bool isTailCall, + unsigned CallingConv) { assert(F && "Need a Function to make a CallInst"); assert(BB && "Need a BasicBlock to make a CallInst"); @@ -181,7 +162,8 @@ Oprnds.push_back(*PI); } - Instruction* result = new CallInst(F,Oprnds,"autoupgrade_call"); + Instruction *result = new CallInst(F, Oprnds); + if (result->getType() != Type::VoidTy) result->setName("autoupgrade_call"); if (isTailCall) cast(result)->setTailCall(); if (CallingConv) cast(result)->setCallingConv(CallingConv); if (signedArg) { @@ -193,35 +175,34 @@ return result; } -Instruction* llvm::UpgradeIntrinsicCall(CallInst *CI, Function* newF) { +// UpgradeIntrinsicCall - In the BC reader, change a call to some intrinsic to +// be a called to the specified intrinsic. We expect the callees to have the +// same number of arguments, but their types may be different. +void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Function *F = CI->getCalledFunction(); - if (const Type* Ty = - (newF ? getTypeFromFunction(newF) : getTypeFromFunctionName(F))) { - std::vector Oprnds; - User::op_iterator OI = CI->op_begin(); - ++OI; - for (User::op_iterator OE = CI->op_end() ; OI != OE; ++OI) { - const Type* opTy = OI->get()->getType(); - if (opTy->isSigned()) - Oprnds.push_back( - new CastInst(OI->get(),opTy->getUnsignedVersion(), - "autoupgrade_cast",CI)); - else - Oprnds.push_back(*OI); + + const FunctionType *NewFnTy = NewFn->getFunctionType(); + std::vector Oprnds; + for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) { + Value *V = CI->getOperand(i); + if (V->getType() != NewFnTy->getParamType(i-1)) + V = new CastInst(V, NewFnTy->getParamType(i-1), V->getName(), CI); + Oprnds.push_back(V); + } + CallInst *NewCI = new CallInst(NewFn, Oprnds, CI->getName(), CI); + NewCI->setTailCall(CI->isTailCall()); + NewCI->setCallingConv(CI->getCallingConv()); + + if (!CI->use_empty()) { + Instruction *RetVal = NewCI; + if (F->getReturnType() != NewFn->getReturnType()) { + RetVal = new CastInst(NewCI, NewFn->getReturnType(), + NewCI->getName(), CI); + NewCI->moveBefore(RetVal); } - CallInst* newCI = new CallInst((newF?newF:F),Oprnds,"autoupgrade_call",CI); - newCI->setTailCall(CI->isTailCall()); - newCI->setCallingConv(CI->getCallingConv()); - if (const Type* oldType = CI->getCalledFunction()->getReturnType()) - if (oldType->isSigned()) { - CastInst* final = - new CastInst(newCI, oldType, "autoupgrade_uncast",newCI); - newCI->moveBefore(final); - return final; - } - return newCI; + CI->replaceAllUsesWith(RetVal); } - return 0; + CI->eraseFromParent(); } bool llvm::UpgradeCallsToIntrinsic(Function* F) { @@ -238,22 +219,24 @@ Oprnds.push_back( new CastInst(OI->get(),opTy->getUnsignedVersion(), "autoupgrade_cast",CI)); - } - else + } else { Oprnds.push_back(*OI); + } } - CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI); + CallInst* newCI = new CallInst(newF, Oprnds, + CI->hasName() ? "autoupcall" : "", CI); newCI->setTailCall(CI->isTailCall()); newCI->setCallingConv(CI->getCallingConv()); - if (const Type* Ty = CI->getCalledFunction()->getReturnType()) - if (Ty->isSigned()) { - CastInst* final = - new CastInst(newCI, Ty, "autoupgrade_uncast",newCI); - newCI->moveBefore(final); - CI->replaceAllUsesWith(final); - } else { - CI->replaceAllUsesWith(newCI); - } + if (CI->use_empty()) { + // noop + } else if (CI->getType() != newCI->getType()) { + CastInst *final = new CastInst(newCI, CI->getType(), + "autoupgrade_uncast", newCI); + newCI->moveBefore(final); + CI->replaceAllUsesWith(final); + } else { + CI->replaceAllUsesWith(newCI); + } CI->eraseFromParent(); } } Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.100 llvm/lib/VMCore/Function.cpp:1.101 --- llvm/lib/VMCore/Function.cpp:1.100 Mon Jan 16 15:12:35 2006 +++ llvm/lib/VMCore/Function.cpp Thu Mar 2 17:58:40 2006 @@ -252,9 +252,12 @@ if (Name == "llvm.longjmp") return Intrinsic::longjmp; break; case 'm': - if (Name == "llvm.memcpy") return Intrinsic::memcpy; - if (Name == "llvm.memmove") return Intrinsic::memmove; - if (Name == "llvm.memset") return Intrinsic::memset; + if (Name == "llvm.memcpy.i32") return Intrinsic::memcpy_i32; + if (Name == "llvm.memcpy.i64") return Intrinsic::memcpy_i64; + if (Name == "llvm.memmove.i32") return Intrinsic::memmove_i32; + if (Name == "llvm.memmove.i64") return Intrinsic::memmove_i64; + if (Name == "llvm.memset.i32") return Intrinsic::memset_i32; + if (Name == "llvm.memset.i64") return Intrinsic::memset_i64; break; case 'p': if (Name == "llvm.prefetch") return Intrinsic::prefetch; Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.146 llvm/lib/VMCore/Verifier.cpp:1.147 --- llvm/lib/VMCore/Verifier.cpp:1.146 Wed Jan 25 18:08:45 2006 +++ llvm/lib/VMCore/Verifier.cpp Thu Mar 2 17:58:40 2006 @@ -956,9 +956,12 @@ case Intrinsic::dbg_func_start: NumArgs = 1; break; case Intrinsic::dbg_declare: NumArgs = 1; break; - case Intrinsic::memcpy: NumArgs = 4; break; - case Intrinsic::memmove: NumArgs = 4; break; - case Intrinsic::memset: NumArgs = 4; break; + case Intrinsic::memcpy_i32: NumArgs = 4; break; + case Intrinsic::memcpy_i64: NumArgs = 4; break; + case Intrinsic::memmove_i32: NumArgs = 4; break; + case Intrinsic::memmove_i64: NumArgs = 4; break; + case Intrinsic::memset_i32: NumArgs = 4; break; + case Intrinsic::memset_i64: NumArgs = 4; break; case Intrinsic::stacksave: NumArgs = 0; From lattner at cs.uiuc.edu Thu Mar 2 17:59:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 17:59:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Message-ID: <200603022359.RAA02379@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.188 -> 1.189 --- Log message: Simplify the autoupgrade interface --- Diffs of the changes: (+3 -6) Reader.cpp | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.188 llvm/lib/Bytecode/Reader/Reader.cpp:1.189 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.188 Fri Jan 27 05:49:27 2006 +++ llvm/lib/Bytecode/Reader/Reader.cpp Thu Mar 2 17:59:12 2006 @@ -1865,11 +1865,8 @@ if (CallInst* CI = dyn_cast(II)) { std::map::iterator FI = upgradedFunctions.find(CI->getCalledFunction()); - if (FI != upgradedFunctions.end()) { - Instruction* newI = UpgradeIntrinsicCall(CI,FI->second); - CI->replaceAllUsesWith(newI); - CI->eraseFromParent(); - } + if (FI != upgradedFunctions.end()) + UpgradeIntrinsicCall(CI, FI->second); } } @@ -2444,7 +2441,7 @@ for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); FI != FE; ++FI) if (Function* newF = UpgradeIntrinsicFunction(FI)) { - upgradedFunctions.insert(std::make_pair(FI,newF)); + upgradedFunctions.insert(std::make_pair(FI, newF)); FI->setName(""); } From lattner at cs.uiuc.edu Thu Mar 2 18:00:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:00:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200603030000.SAA02482@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.175 -> 1.176 --- Log message: Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving PR709: http://llvm.cs.uiuc.edu/PR709 , and paving the way for future progress. --- Diffs of the changes: (+12 -3) SelectionDAGISel.cpp | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.175 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.176 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.175 Tue Feb 28 19:09:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Mar 2 18:00:25 2006 @@ -955,9 +955,18 @@ case Intrinsic::longjmp: return "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); break; - case Intrinsic::memcpy: visitMemIntrinsic(I, ISD::MEMCPY); return 0; - case Intrinsic::memset: visitMemIntrinsic(I, ISD::MEMSET); return 0; - case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return 0; + case Intrinsic::memcpy_i32: + case Intrinsic::memcpy_i64: + visitMemIntrinsic(I, ISD::MEMCPY); + return 0; + case Intrinsic::memset_i32: + case Intrinsic::memset_i64: + visitMemIntrinsic(I, ISD::MEMSET); + return 0; + case Intrinsic::memmove_i32: + case Intrinsic::memmove_i64: + visitMemIntrinsic(I, ISD::MEMMOVE); + return 0; case Intrinsic::readport: case Intrinsic::readio: { From lattner at cs.uiuc.edu Thu Mar 2 18:00:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:00:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200603030000.SAA02486@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.139 -> 1.140 --- Log message: Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving PR709: http://llvm.cs.uiuc.edu/PR709 , and paving the way for future progress. --- Diffs of the changes: (+6 -3) Local.cpp | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.139 llvm/lib/Analysis/DataStructure/Local.cpp:1.140 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.139 Sun Jan 22 16:52:03 2006 +++ llvm/lib/Analysis/DataStructure/Local.cpp Thu Mar 2 18:00:25 2006 @@ -545,8 +545,10 @@ return; case Intrinsic::vaend: return; // noop - case Intrinsic::memmove: - case Intrinsic::memcpy: { + case Intrinsic::memmove_i32: + case Intrinsic::memcpy_i32: + case Intrinsic::memmove_i64: + case Intrinsic::memcpy_i64: { // Merge the first & second arguments, and mark the memory read and // modified. DSNodeHandle RetNH = getValueDest(**CS.arg_begin()); @@ -555,7 +557,8 @@ N->setModifiedMarker()->setReadMarker(); return; } - case Intrinsic::memset: + case Intrinsic::memset_i32: + case Intrinsic::memset_i64: // Mark the memory modified. if (DSNode *N = getValueDest(**CS.arg_begin()).getNode()) N->setModifiedMarker(); From lattner at cs.uiuc.edu Thu Mar 2 18:00:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:00:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IntrinsicLowering.cpp Message-ID: <200603030000.SAA02490@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IntrinsicLowering.cpp updated: 1.39 -> 1.40 --- Log message: Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving PR709: http://llvm.cs.uiuc.edu/PR709 , and paving the way for future progress. --- Diffs of the changes: (+12 -6) IntrinsicLowering.cpp | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/IntrinsicLowering.cpp diff -u llvm/lib/CodeGen/IntrinsicLowering.cpp:1.39 llvm/lib/CodeGen/IntrinsicLowering.cpp:1.40 --- llvm/lib/CodeGen/IntrinsicLowering.cpp:1.39 Mon Jan 16 15:12:35 2006 +++ llvm/lib/CodeGen/IntrinsicLowering.cpp Thu Mar 2 18:00:25 2006 @@ -99,15 +99,18 @@ EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), Type::VoidTy); break; - case Intrinsic::memcpy: + case Intrinsic::memcpy_i32: + case Intrinsic::memcpy_i64: EnsureFunctionExists(M, "memcpy", I->arg_begin(), --I->arg_end(), I->arg_begin()->getType()); break; - case Intrinsic::memmove: + case Intrinsic::memmove_i32: + case Intrinsic::memmove_i64: EnsureFunctionExists(M, "memmove", I->arg_begin(), --I->arg_end(), I->arg_begin()->getType()); break; - case Intrinsic::memset: + case Intrinsic::memset_i32: + case Intrinsic::memset_i64: M.getOrInsertFunction("memset", PointerType::get(Type::SByteTy), PointerType::get(Type::SByteTy), Type::IntTy, (--(--I->arg_end()))->getType(), @@ -405,7 +408,8 @@ CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); break; // Simply strip out debugging intrinsics - case Intrinsic::memcpy: { + case Intrinsic::memcpy_i32: + case Intrinsic::memcpy_i64: { // The memcpy intrinsic take an extra alignment argument that the memcpy // libc function does not. static Function *MemcpyFCache = 0; @@ -413,7 +417,8 @@ (*(CI->op_begin()+1))->getType(), MemcpyFCache); break; } - case Intrinsic::memmove: { + case Intrinsic::memmove_i32: + case Intrinsic::memmove_i64: { // The memmove intrinsic take an extra alignment argument that the memmove // libc function does not. static Function *MemmoveFCache = 0; @@ -421,7 +426,8 @@ (*(CI->op_begin()+1))->getType(), MemmoveFCache); break; } - case Intrinsic::memset: { + case Intrinsic::memset_i32: + case Intrinsic::memset_i64: { // The memset intrinsic take an extra alignment argument that the memset // libc function does not. static Function *MemsetFCache = 0; From lattner at cs.uiuc.edu Thu Mar 2 18:07:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:07:32 -0600 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200603030007.SAA02619@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.135 -> 1.136 --- Log message: Update the llvm.memset/memcpy/memmove intrinsics to reflect the recent split into types. --- Diffs of the changes: (+33 -26) LangRef.html | 59 +++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 33 insertions(+), 26 deletions(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.135 llvm/docs/LangRef.html:1.136 --- llvm/docs/LangRef.html:1.135 Fri Feb 17 15:18:08 2006 +++ llvm/docs/LangRef.html Thu Mar 2 18:07:20 2006 @@ -152,9 +152,9 @@
  • Standard C Library Intrinsics
      -
    1. 'llvm.memcpy' Intrinsic
    2. -
    3. 'llvm.memmove' Intrinsic
    4. -
    5. 'llvm.memset' Intrinsic
    6. +
    7. 'llvm.memcpy.*' Intrinsic
    8. +
    9. 'llvm.memmove.*' Intrinsic
    10. +
    11. 'llvm.memset.*' Intrinsic
    12. 'llvm.isunordered.*' Intrinsic
    13. 'llvm.sqrt.*' Intrinsic
    14. @@ -3483,27 +3483,29 @@
      Syntax:
      -  declare void %llvm.memcpy(sbyte* <dest>, sbyte* <src>,
      -                            uint <len>, uint <align>)
      +  declare void %llvm.memcpy.i32(sbyte* <dest>, sbyte* <src>,
      +                                uint <len>, uint <align>)
      +  declare void %llvm.memcpy.i64(sbyte* <dest>, sbyte* <src>,
      +                                ulong <len>, uint <align>)
       
      Overview:

      -The 'llvm.memcpy' intrinsic copies a block of memory from the source +The 'llvm.memcpy.*' intrinsics copy a block of memory from the source location to the destination location.

      -Note that, unlike the standard libc function, the llvm.memcpy intrinsic -does not return a value, and takes an extra alignment argument. +Note that, unlike the standard libc function, the llvm.memcpy.* +intrinsics do not return a value, and takes an extra alignment argument.

      Arguments:

      The first argument is a pointer to the destination, the second is a pointer to -the source. The third argument is an (arbitrarily sized) integer argument +the source. The third argument is an integer argument specifying the number of bytes to copy, and the fourth argument is the alignment of the source and destination locations.

      @@ -3517,7 +3519,7 @@
      Semantics:

      -The 'llvm.memcpy' intrinsic copies a block of memory from the source +The 'llvm.memcpy.*' intrinsics copy a block of memory from the source location to the destination location, which are not allowed to overlap. It copies "len" bytes of memory over. If the argument is known to be aligned to some boundary, this can be specified as the fourth argument, otherwise it should @@ -3535,28 +3537,30 @@

      Syntax:
      -  declare void %llvm.memmove(sbyte* <dest>, sbyte* <src>,
      -                             uint <len>, uint <align>)
      +  declare void %llvm.memmove.i32(sbyte* <dest>, sbyte* <src>,
      +                                 uint <len>, uint <align>)
      +  declare void %llvm.memmove.i64(sbyte* <dest>, sbyte* <src>,
      +                                 ulong <len>, uint <align>)
       
      Overview:

      -The 'llvm.memmove' intrinsic moves a block of memory from the source -location to the destination location. It is similar to the 'llvm.memcpy' -intrinsic but allows the two memory locations to overlap. +The 'llvm.memmove.*' intrinsics move a block of memory from the source +location to the destination location. It is similar to the +'llvm.memcmp' intrinsic but allows the two memory locations to overlap.

      -Note that, unlike the standard libc function, the llvm.memmove intrinsic -does not return a value, and takes an extra alignment argument. +Note that, unlike the standard libc function, the llvm.memmove.* +intrinsics do not return a value, and takes an extra alignment argument.

      Arguments:

      The first argument is a pointer to the destination, the second is a pointer to -the source. The third argument is an (arbitrarily sized) integer argument +the source. The third argument is an integer argument specifying the number of bytes to copy, and the fourth argument is the alignment of the source and destination locations.

      @@ -3570,7 +3574,7 @@
      Semantics:

      -The 'llvm.memmove' intrinsic copies a block of memory from the source +The 'llvm.memmove.*' intrinsics copy a block of memory from the source location to the destination location, which may overlap. It copies "len" bytes of memory over. If the argument is known to be aligned to some boundary, this can be specified as the fourth argument, otherwise it should @@ -3581,21 +3585,23 @@

      Syntax:
      -  declare void %llvm.memset(sbyte* <dest>, ubyte <val>,
      -                            uint <len>, uint <align>)
      +  declare void %llvm.memset.i32(sbyte* <dest>, ubyte <val>,
      +                                uint <len>, uint <align>)
      +  declare void %llvm.memset.i64(sbyte* <dest>, ubyte <val>,
      +                                ulong <len>, uint <align>)
       
      Overview:

      -The 'llvm.memset' intrinsic fills a block of memory with a particular +The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte value.

      @@ -3608,7 +3614,7 @@

      The first argument is a pointer to the destination to fill, the second is the -byte value to fill it with, the third argument is an (arbitrarily sized) integer +byte value to fill it with, the third argument is an integer argument specifying the number of bytes to fill, and the fourth argument is the known alignment of destination location.

      @@ -3622,7 +3628,8 @@
      Semantics:

      -The 'llvm.memset' intrinsic fills "len" bytes of memory starting at the +The 'llvm.memset.*' intrinsics fill "len" bytes of memory starting at +the destination location. If the argument is known to be aligned to some boundary, this can be specified as the fourth argument, otherwise it should be set to 0 or 1. @@ -3888,7 +3895,7 @@ Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2006/02/17 21:18:08 $ + Last modified: $Date: 2006/03/03 00:07:20 $ From lattner at cs.uiuc.edu Thu Mar 2 18:16:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:16:37 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/io.llx ioport.llx Message-ID: <200603030016.SAA02728@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: io.llx (r1.1) removed ioport.llx (r1.2) removed --- Log message: Remove these testcases. These intrinsics are going away --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Thu Mar 2 18:18:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:18:11 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.h Message-ID: <200603030018.SAA02814@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.h updated: 1.37 -> 1.38 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+0 -7) Intrinsics.h | 7 ------- 1 files changed, 7 deletions(-) Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.37 llvm/include/llvm/Intrinsics.h:1.38 --- llvm/include/llvm/Intrinsics.h:1.37 Thu Mar 2 17:57:16 2006 +++ llvm/include/llvm/Intrinsics.h Thu Mar 2 18:18:00 2006 @@ -86,13 +86,6 @@ cttz_i16, // Count trailing zeros of short cttz_i32, // Count trailing zeros of int cttz_i64, // Count trailing zeros of long - - // Input/Output intrinsics. - readport, - writeport, - readio, - writeio - }; } // End Intrinsic namespace From lattner at cs.uiuc.edu Thu Mar 2 18:18:12 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:18:12 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200603030018.SAA02818@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.105 -> 1.106 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+0 -6) SelectionDAGNodes.h | 6 ------ 1 files changed, 6 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.105 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.106 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.105 Tue Feb 28 18:51:13 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Thu Mar 2 18:18:00 2006 @@ -379,12 +379,6 @@ // register (or other high accuracy low latency clock source) READCYCLECOUNTER, - // READPORT, WRITEPORT, READIO, WRITEIO - These correspond to the LLVM - // intrinsics of the same name. The first operand is a token chain, the - // other operands match the intrinsic. These produce a token chain in - // addition to a value (if any). - READPORT, WRITEPORT, READIO, WRITEIO, - // HANDLENODE node - Used as a handle for various purposes. HANDLENODE, From lattner at cs.uiuc.edu Thu Mar 2 18:19:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:19:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86InstrInfo.td Message-ID: <200603030019.SAA02923@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.98 -> 1.99 X86InstrInfo.td updated: 1.250 -> 1.251 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+12 -21) X86ISelLowering.cpp | 9 --------- X86InstrInfo.td | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 21 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.98 llvm/lib/Target/X86/X86ISelLowering.cpp:1.99 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.98 Tue Feb 28 19:11:20 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Mar 2 18:19:44 2006 @@ -137,15 +137,6 @@ setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom); setOperationAction(ISD::BSWAP , MVT::i16 , Expand); - setOperationAction(ISD::READIO , MVT::i1 , Expand); - setOperationAction(ISD::READIO , MVT::i8 , Expand); - setOperationAction(ISD::READIO , MVT::i16 , Expand); - setOperationAction(ISD::READIO , MVT::i32 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i1 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); - // These should be promoted to a larger select which is supported. setOperationAction(ISD::SELECT , MVT::i1 , Promote); setOperationAction(ISD::SELECT , MVT::i8 , Promote); Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.250 llvm/lib/Target/X86/X86InstrInfo.td:1.251 --- llvm/lib/Target/X86/X86InstrInfo.td:1.250 Sat Feb 25 04:02:21 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Thu Mar 2 18:19:44 2006 @@ -581,48 +581,48 @@ // def IN8rr : I<0xEC, RawFrm, (ops), "in{b} {%dx, %al|%AL, %DX}", - [(set AL, (readport DX))]>, Imp<[DX], [AL]>; + []>, Imp<[DX], [AL]>; def IN16rr : I<0xED, RawFrm, (ops), "in{w} {%dx, %ax|%AX, %DX}", - [(set AX, (readport DX))]>, Imp<[DX], [AX]>, OpSize; + []>, Imp<[DX], [AX]>, OpSize; def IN32rr : I<0xED, RawFrm, (ops), "in{l} {%dx, %eax|%EAX, %DX}", - [(set EAX, (readport DX))]>, Imp<[DX],[EAX]>; + []>, Imp<[DX],[EAX]>; def IN8ri : Ii8<0xE4, RawFrm, (ops i16i8imm:$port), "in{b} {$port, %al|%AL, $port}", - [(set AL, (readport i16immZExt8:$port))]>, + []>, Imp<[], [AL]>; def IN16ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port), "in{w} {$port, %ax|%AX, $port}", - [(set AX, (readport i16immZExt8:$port))]>, + []>, Imp<[], [AX]>, OpSize; def IN32ri : Ii8<0xE5, RawFrm, (ops i16i8imm:$port), "in{l} {$port, %eax|%EAX, $port}", - [(set EAX, (readport i16immZExt8:$port))]>, + []>, Imp<[],[EAX]>; def OUT8rr : I<0xEE, RawFrm, (ops), "out{b} {%al, %dx|%DX, %AL}", - [(writeport AL, DX)]>, Imp<[DX, AL], []>; + []>, Imp<[DX, AL], []>; def OUT16rr : I<0xEF, RawFrm, (ops), "out{w} {%ax, %dx|%DX, %AX}", - [(writeport AX, DX)]>, Imp<[DX, AX], []>, OpSize; + []>, Imp<[DX, AX], []>, OpSize; def OUT32rr : I<0xEF, RawFrm, (ops), "out{l} {%eax, %dx|%DX, %EAX}", - [(writeport EAX, DX)]>, Imp<[DX, EAX], []>; + []>, Imp<[DX, EAX], []>; def OUT8ir : Ii8<0xE6, RawFrm, (ops i16i8imm:$port), "out{b} {%al, $port|$port, %AL}", - [(writeport AL, i16immZExt8:$port)]>, + []>, Imp<[AL], []>; def OUT16ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port), "out{w} {%ax, $port|$port, %AX}", - [(writeport AX, i16immZExt8:$port)]>, + []>, Imp<[AX], []>, OpSize; def OUT32ir : Ii8<0xE7, RawFrm, (ops i16i8imm:$port), "out{l} {%eax, $port|$port, %EAX}", - [(writeport EAX, i16immZExt8:$port)]>, + []>, Imp<[EAX], []>; //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Thu Mar 2 18:19:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:19:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200603030019.SAA02935@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.308 -> 1.309 SelectionDAG.cpp updated: 1.262 -> 1.263 SelectionDAGISel.cpp updated: 1.176 -> 1.177 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+0 -91) LegalizeDAG.cpp | 62 --------------------------------------------------- SelectionDAG.cpp | 6 ---- SelectionDAGISel.cpp | 23 ------------------ 3 files changed, 91 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.308 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.309 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.308 Tue Feb 28 19:09:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Mar 2 18:19:44 2006 @@ -1691,68 +1691,6 @@ break; } - case ISD::READPORT: - Tmp1 = LegalizeOp(Node->getOperand(0)); - Tmp2 = LegalizeOp(Node->getOperand(1)); - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); - - // Since these produce two values, make sure to remember that we legalized - // both of them. - AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); - AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); - return Result; - case ISD::WRITEPORT: - Tmp1 = LegalizeOp(Node->getOperand(0)); - Tmp2 = LegalizeOp(Node->getOperand(1)); - Tmp3 = LegalizeOp(Node->getOperand(2)); - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); - break; - - case ISD::READIO: - Tmp1 = LegalizeOp(Node->getOperand(0)); - Tmp2 = LegalizeOp(Node->getOperand(1)); - - switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { - case TargetLowering::Custom: - default: assert(0 && "This action not implemented for this operation!"); - case TargetLowering::Legal: - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); - break; - case TargetLowering::Expand: - // Replace this with a load from memory. - Result = DAG.getLoad(Node->getValueType(0), Node->getOperand(0), - Node->getOperand(1), DAG.getSrcValue(NULL)); - Result = LegalizeOp(Result); - break; - } - - // Since these produce two values, make sure to remember that we legalized - // both of them. - AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); - AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); - return Result.getValue(Op.ResNo); - - case ISD::WRITEIO: - Tmp1 = LegalizeOp(Node->getOperand(0)); - Tmp2 = LegalizeOp(Node->getOperand(1)); - Tmp3 = LegalizeOp(Node->getOperand(2)); - - switch (TLI.getOperationAction(Node->getOpcode(), - Node->getOperand(1).getValueType())) { - case TargetLowering::Custom: - default: assert(0 && "This action not implemented for this operation!"); - case TargetLowering::Legal: - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); - break; - case TargetLowering::Expand: - // Replace this with a store to memory. - Result = DAG.getNode(ISD::STORE, MVT::Other, Node->getOperand(0), - Node->getOperand(1), Node->getOperand(2), - DAG.getSrcValue(NULL)); - break; - } - break; - case ISD::SHL_PARTS: case ISD::SRA_PARTS: case ISD::SRL_PARTS: { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.262 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.263 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.262 Tue Feb 28 18:51:13 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Mar 2 18:19:44 2006 @@ -2691,12 +2691,6 @@ case ISD::CTTZ: return "cttz"; case ISD::CTLZ: return "ctlz"; - // IO Intrinsics - case ISD::READPORT: return "readport"; - case ISD::WRITEPORT: return "writeport"; - case ISD::READIO: return "readio"; - case ISD::WRITEIO: return "writeio"; - // Debug info case ISD::LOCATION: return "location"; case ISD::DEBUG_LOC: return "debug_loc"; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.176 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.177 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.176 Thu Mar 2 18:00:25 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Mar 2 18:19:44 2006 @@ -968,29 +968,6 @@ visitMemIntrinsic(I, ISD::MEMMOVE); return 0; - case Intrinsic::readport: - case Intrinsic::readio: { - std::vector VTs; - VTs.push_back(TLI.getValueType(I.getType())); - VTs.push_back(MVT::Other); - std::vector Ops; - Ops.push_back(getRoot()); - Ops.push_back(getValue(I.getOperand(1))); - SDOperand Tmp = DAG.getNode(Intrinsic == Intrinsic::readport ? - ISD::READPORT : ISD::READIO, VTs, Ops); - - setValue(&I, Tmp); - DAG.setRoot(Tmp.getValue(1)); - return 0; - } - case Intrinsic::writeport: - case Intrinsic::writeio: - DAG.setRoot(DAG.getNode(Intrinsic == Intrinsic::writeport ? - ISD::WRITEPORT : ISD::WRITEIO, MVT::Other, - getRoot(), getValue(I.getOperand(1)), - getValue(I.getOperand(2)))); - return 0; - case Intrinsic::dbg_stoppoint: { if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) return "llvm_debugger_stop"; From lattner at cs.uiuc.edu Thu Mar 2 18:19:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:19:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200603030019.SAA02927@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.48 -> 1.49 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+0 -11) TargetSelectionDAG.td | 11 ----------- 1 files changed, 11 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.48 llvm/lib/Target/TargetSelectionDAG.td:1.49 --- llvm/lib/Target/TargetSelectionDAG.td:1.48 Thu Feb 16 23:43:56 2006 +++ llvm/lib/Target/TargetSelectionDAG.td Thu Mar 2 18:19:44 2006 @@ -138,14 +138,6 @@ def SDTRet : SDTypeProfile<0, 0, []>; // ret -def SDTReadPort : SDTypeProfile<1, 1, [ // readport - SDTCisInt<0>, SDTCisInt<1> -]>; - -def SDTWritePort : SDTypeProfile<0, 2, [ // writeport - SDTCisInt<0>, SDTCisInt<1> -]>; - def SDTLoad : SDTypeProfile<1, 1, [ // load SDTCisPtrTy<1> ]>; @@ -284,9 +276,6 @@ def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; def ret : SDNode<"ISD::RET" , SDTRet, [SDNPHasChain]>; -def readport : SDNode<"ISD::READPORT" , SDTReadPort, [SDNPHasChain]>; -def writeport : SDNode<"ISD::WRITEPORT" , SDTWritePort, [SDNPHasChain]>; - def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>; From lattner at cs.uiuc.edu Thu Mar 2 18:19:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:19:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200603030019.SAA02941@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.101 -> 1.102 Verifier.cpp updated: 1.147 -> 1.148 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+0 -51) Function.cpp | 6 ------ Verifier.cpp | 45 --------------------------------------------- 2 files changed, 51 deletions(-) Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.101 llvm/lib/VMCore/Function.cpp:1.102 --- llvm/lib/VMCore/Function.cpp:1.101 Thu Mar 2 17:58:40 2006 +++ llvm/lib/VMCore/Function.cpp Thu Mar 2 18:19:44 2006 @@ -265,8 +265,6 @@ break; case 'r': if (Name == "llvm.returnaddress") return Intrinsic::returnaddress; - if (Name == "llvm.readport") return Intrinsic::readport; - if (Name == "llvm.readio") return Intrinsic::readio; if (Name == "llvm.readcyclecounter") return Intrinsic::readcyclecounter; break; case 's': @@ -283,10 +281,6 @@ if (Name == "llvm.va_end") return Intrinsic::vaend; if (Name == "llvm.va_start") return Intrinsic::vastart; break; - case 'w': - if (Name == "llvm.writeport") return Intrinsic::writeport; - if (Name == "llvm.writeio") return Intrinsic::writeio; - break; } // The "llvm." namespace is reserved! assert(!"Unknown LLVM intrinsic function!"); Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.147 llvm/lib/VMCore/Verifier.cpp:1.148 --- llvm/lib/VMCore/Verifier.cpp:1.147 Thu Mar 2 17:58:40 2006 +++ llvm/lib/VMCore/Verifier.cpp Thu Mar 2 18:19:44 2006 @@ -702,51 +702,6 @@ NumArgs = 1; break; - // Verify that read and write port have integral parameters of the correct - // signed-ness. - case Intrinsic::writeport: - Assert1(FT->getNumParams() == 2, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getParamType(0)->isIntegral(), - "First argument not unsigned int!", IF); - Assert1(FT->getParamType(1)->isUnsigned(), - "First argument not unsigned int!", IF); - NumArgs = 2; - break; - - case Intrinsic::writeio: - Assert1(FT->getNumParams() == 2, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getParamType(0)->isFirstClassType(), - "First argument not a first class type!", IF); - Assert1(isa(FT->getParamType(1)), - "Second argument not a pointer!", IF); - NumArgs = 2; - break; - - case Intrinsic::readport: - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType()->isFirstClassType(), - "Return type is not a first class type!", IF); - Assert1(FT->getParamType(0)->isUnsigned(), - "First argument not unsigned int!", IF); - NumArgs = 1; - break; - - case Intrinsic::readio: { - const PointerType *ParamType = dyn_cast(FT->getParamType(0)); - const Type *ReturnType = FT->getReturnType(); - - Assert1(FT->getNumParams() == 1, - "Illegal # arguments for intrinsic function!", IF); - Assert1(ParamType, "First argument not a pointer!", IF); - Assert1(ParamType->getElementType() == ReturnType, - "Pointer type doesn't match return type!", IF); - NumArgs = 1; - break; - } - case Intrinsic::isunordered_f32: Assert1(FT->getNumParams() == 2, "Illegal # arguments for intrinsic function!", IF); From lattner at cs.uiuc.edu Thu Mar 2 18:20:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:20:11 -0600 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200603030020.SAA02975@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.136 -> 1.137 --- Log message: remove the read/write port/io intrinsics. --- Diffs of the changes: (+1 -201) LangRef.html | 202 ----------------------------------------------------------- 1 files changed, 1 insertion(+), 201 deletions(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.136 llvm/docs/LangRef.html:1.137 --- llvm/docs/LangRef.html:1.136 Thu Mar 2 18:07:20 2006 +++ llvm/docs/LangRef.html Thu Mar 2 18:19:58 2006 @@ -143,13 +143,6 @@

    15. llvm.readcyclecounter' Intrinsic
  • -
  • Operating System Intrinsics -
      -
    1. 'llvm.readport' Intrinsic
    2. -
    3. 'llvm.writeport' Intrinsic
    4. -
    5. 'llvm.readio' Intrinsic
    6. -
    7. 'llvm.writeio' Intrinsic
    8. -
  • Standard C Library Intrinsics
    1. 'llvm.memcpy.*' Intrinsic
    2. @@ -3266,199 +3259,6 @@ - - - - -
      -

      -These intrinsics are provided by LLVM to support the implementation of -operating system level code. -

      - -
      - - - - -
      - -
      Syntax:
      -
      -  declare <integer type> %llvm.readport (<integer type> <address>)
      -
      - -
      Overview:
      - -

      -The 'llvm.readport' intrinsic reads data from the specified hardware -I/O port. -

      - -
      Arguments:
      - -

      -The argument to this intrinsic indicates the hardware I/O address from which -to read the data. The address is in the hardware I/O address namespace (as -opposed to being a memory location for memory mapped I/O). -

      - -
      Semantics:
      - -

      -The 'llvm.readport' intrinsic reads data from the hardware I/O port -specified by address and returns the value. The address and return -value must be integers, but the size is dependent upon the platform upon which -the program is code generated. For example, on x86, the address must be an -unsigned 16-bit value, and the return value must be 8, 16, or 32 bits. -

      - -
      - - - - -
      - -
      Syntax:
      -
      -  call void (<integer type>, <integer type>)*
      -            %llvm.writeport (<integer type> <value>,
      -                             <integer type> <address>)
      -
      - -
      Overview:
      - -

      -The 'llvm.writeport' intrinsic writes data to the specified hardware -I/O port. -

      - -
      Arguments:
      - -

      -The first argument is the value to write to the I/O port. -

      - -

      -The second argument indicates the hardware I/O address to which data should be -written. The address is in the hardware I/O address namespace (as opposed to -being a memory location for memory mapped I/O). -

      - -
      Semantics:
      - -

      -The 'llvm.writeport' intrinsic writes value to the I/O port -specified by address. The address and value must be integers, but the -size is dependent upon the platform upon which the program is code generated. -For example, on x86, the address must be an unsigned 16-bit value, and the -value written must be 8, 16, or 32 bits in length. -

      - -
      - - - - -
      - -
      Syntax:
      -
      -  declare <result> %llvm.readio (<ty> * <pointer>)
      -
      - -
      Overview:
      - -

      -The 'llvm.readio' intrinsic reads data from a memory mapped I/O -address. -

      - -
      Arguments:
      - -

      -The argument to this intrinsic is a pointer indicating the memory address from -which to read the data. The data must be a -first class type. -

      - -
      Semantics:
      - -

      -The 'llvm.readio' intrinsic reads data from a memory mapped I/O -location specified by pointer and returns the value. The argument must -be a pointer, and the return value must be a -first class type. However, certain architectures -may not support I/O on all first class types. For example, 32-bit processors -may only support I/O on data types that are 32 bits or less. -

      - -

      -This intrinsic enforces an in-order memory model for llvm.readio and -llvm.writeio calls on machines that use dynamic scheduling. Dynamically -scheduled processors may execute loads and stores out of order, re-ordering at -run time accesses to memory mapped I/O registers. Using these intrinsics -ensures that accesses to memory mapped I/O registers occur in program order. -

      - -
      - - - - -
      - -
      Syntax:
      -
      -  declare void %llvm.writeio (<ty1> <value>, <ty2> * <pointer>)
      -
      - -
      Overview:
      - -

      -The 'llvm.writeio' intrinsic writes data to the specified memory -mapped I/O address. -

      - -
      Arguments:
      - -

      -The first argument is the value to write to the memory mapped I/O location. -The second argument is a pointer indicating the memory address to which the -data should be written. -

      - -
      Semantics:
      - -

      -The 'llvm.writeio' intrinsic writes value to the memory mapped -I/O address specified by pointer. The value must be a -first class type. However, certain architectures -may not support I/O on all first class types. For example, 32-bit processors -may only support I/O on data types that are 32 bits or less. -

      - -

      -This intrinsic enforces an in-order memory model for llvm.readio and -llvm.writeio calls on machines that use dynamic scheduling. Dynamically -scheduled processors may execute loads and stores out of order, re-ordering at -run time accesses to memory mapped I/O registers. Using these intrinsics -ensures that accesses to memory mapped I/O registers occur in program order. -

      - -
      -
      Standard C Library Intrinsics @@ -3895,7 +3695,7 @@ Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2006/03/03 00:07:20 $ + Last modified: $Date: 2006/03/03 00:19:58 $ From lattner at cs.uiuc.edu Thu Mar 2 18:34:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 18:34:39 -0600 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200603030034.SAA03139@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.346 -> 1.347 --- Log message: mention some major changes --- Diffs of the changes: (+24 -7) ReleaseNotes.html | 31 ++++++++++++++++++++++++------- 1 files changed, 24 insertions(+), 7 deletions(-) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.346 llvm/docs/ReleaseNotes.html:1.347 --- llvm/docs/ReleaseNotes.html:1.346 Sun Feb 5 00:39:36 2006 +++ llvm/docs/ReleaseNotes.html Thu Mar 2 18:34:26 2006 @@ -76,10 +76,26 @@
        +
      • New C front-end.
      • New SPARC backend.
      • +
      • Inline assembly support.
      + + + +
      +
        +
      • Removed the llvm.readport/llvm.writeport/llvm.readio/llvm.writeio + intrinsics.
      • +
      • Separated the other intrinsics based on type.
      • +
      +
      + +
      Portability and Supported Platforms @@ -184,6 +200,10 @@
      Bugs
      + +These bugs are known for the old front-end. The new GCC-4-based C front-end +suffers from none of these. +
      • C99 Variable sized arrays do not release stack memory when they go out of scope. Thus, the following program may run out of stack space: @@ -209,8 +229,6 @@
          -
        • Inline assembly is not yet supported.
        • -
        • "long double" is transformed by the front-end into "double". There is no support for floating point data types of any size other than 32 and 64 bits.
        • @@ -436,8 +454,7 @@ @@ -517,13 +534,13 @@
            -
          • This backend lacks a JIT compiler.
          • +
          • None yet.
          @@ -560,7 +577,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
          - Last modified: $Date: 2006/02/05 06:39:36 $ + Last modified: $Date: 2006/03/03 00:34:26 $ From lattner at cs.uiuc.edu Thu Mar 2 19:21:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:21:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200603030121.TAA03391@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.26 -> 1.27 --- Log message: updates for recent changes --- Diffs of the changes: (+4 -2) Andersens.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.26 llvm/lib/Analysis/IPA/Andersens.cpp:1.27 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.26 Sun Jan 22 17:19:18 2006 +++ llvm/lib/Analysis/IPA/Andersens.cpp Thu Mar 2 19:21:36 2006 @@ -607,7 +607,8 @@ F->getName() == "atol" || F->getName() == "atoll" || F->getName() == "remove" || F->getName() == "unlink" || F->getName() == "rename" || F->getName() == "memcmp" || - F->getName() == "llvm.memset" || + F->getName() == "llvm.memset.i32" || + F->getName() == "llvm.memset.i64" || F->getName() == "strcmp" || F->getName() == "strncmp" || F->getName() == "execl" || F->getName() == "execlp" || F->getName() == "execle" || F->getName() == "execv" || @@ -645,7 +646,8 @@ // These functions do induce points-to edges. - if (F->getName() == "llvm.memcpy" || F->getName() == "llvm.memmove" || + if (F->getName() == "llvm.memcpy.i32" || F->getName() == "llvm.memcpy.i64" || + F->getName() == "llvm.memmove.i32" ||F->getName() == "llvm.memmove.i64" || F->getName() == "memmove") { // Note: this is a poor approximation, this says Dest = Src, instead of // *Dest = *Src. From lattner at cs.uiuc.edu Thu Mar 2 19:30:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:30:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Message-ID: <200603030130.TAA03447@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: SimplifyLibCalls.cpp updated: 1.62 -> 1.63 --- Log message: Make this work with renamed intrinsics. --- Diffs of the changes: (+25 -26) SimplifyLibCalls.cpp | 51 +++++++++++++++++++++++++-------------------------- 1 files changed, 25 insertions(+), 26 deletions(-) Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.62 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.63 --- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.62 Wed Feb 15 15:13:37 2006 +++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Thu Mar 2 19:30:23 2006 @@ -283,8 +283,11 @@ Function* get_memcpy() { if (!memcpy_func) { const Type *SBP = PointerType::get(Type::SByteTy); - memcpy_func = M->getOrInsertFunction("llvm.memcpy", Type::VoidTy,SBP, SBP, - TD->getIntPtrType(), Type::UIntTy, NULL); + const char *N = TD->getIntPtrType() == Type::UIntTy ? + "llvm.memcpy.i32" : "llvm.memcpy.i64"; + memcpy_func = M->getOrInsertFunction(N, Type::VoidTy, SBP, SBP, + TD->getIntPtrType(), Type::UIntTy, + NULL); } return memcpy_func; } @@ -1018,16 +1021,9 @@ /// bytes depending on the length of the string and the alignment. Additional /// optimizations are possible in code generation (sequence of immediate store) /// @brief Simplify the memcpy library function. -struct LLVMMemCpyOptimization : public LibCallOptimization { - /// @brief Default Constructor - LLVMMemCpyOptimization() : LibCallOptimization("llvm.memcpy", - "Number of 'llvm.memcpy' calls simplified") {} - -protected: - /// @brief Subclass Constructor - LLVMMemCpyOptimization(const char* fname, const char* desc) - : LibCallOptimization(fname, desc) {} -public: +struct LLVMMemCpyMoveOptzn : public LibCallOptimization { + LLVMMemCpyMoveOptzn(const char* fname, const char* desc) + : LibCallOptimization(fname, desc) {} /// @brief Make sure that the "memcpy" function has the right prototype virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD) { @@ -1086,27 +1082,26 @@ ci->eraseFromParent(); return true; } -} LLVMMemCpyOptimizer; - -/// This LibCallOptimization will simplify a call to the memmove library -/// function. It is identical to MemCopyOptimization except for the name of -/// the intrinsic. -/// @brief Simplify the memmove library function. -struct LLVMMemMoveOptimization : public LLVMMemCpyOptimization { - /// @brief Default Constructor - LLVMMemMoveOptimization() : LLVMMemCpyOptimization("llvm.memmove", - "Number of 'llvm.memmove' calls simplified") {} +}; -} LLVMMemMoveOptimizer; +/// This LibCallOptimization will simplify a call to the memcpy/memmove library +/// functions. +LLVMMemCpyMoveOptzn LLVMMemCpyOptimizer32("llvm.memcpy.i32", + "Number of 'llvm.memcpy' calls simplified"); +LLVMMemCpyMoveOptzn LLVMMemCpyOptimizer64("llvm.memcpy.i64", + "Number of 'llvm.memcpy' calls simplified"); +LLVMMemCpyMoveOptzn LLVMMemMoveOptimizer32("llvm.memmove.i32", + "Number of 'llvm.memmove' calls simplified"); +LLVMMemCpyMoveOptzn LLVMMemMoveOptimizer64("llvm.memmove.i64", + "Number of 'llvm.memmove' calls simplified"); /// This LibCallOptimization will simplify a call to the memset library /// function by expanding it out to a single store of size 0, 1, 2, 4, or 8 /// bytes depending on the length argument. struct LLVMMemSetOptimization : public LibCallOptimization { /// @brief Default Constructor - LLVMMemSetOptimization() : LibCallOptimization("llvm.memset", + LLVMMemSetOptimization(const char *Name) : LibCallOptimization(Name, "Number of 'llvm.memset' calls simplified") {} -public: /// @brief Make sure that the "memset" function has the right prototype virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) { @@ -1196,7 +1191,11 @@ ci->eraseFromParent(); return true; } -} LLVMMemSetOptimizer; +}; + +LLVMMemSetOptimization MemSet32Optimizer("llvm.memset.i32"); +LLVMMemSetOptimization MemSet64Optimizer("llvm.memset.i64"); + /// This LibCallOptimization will simplify calls to the "pow" library /// function. It looks for cases where the result of pow is well known and From lattner at cs.uiuc.edu Thu Mar 2 19:31:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:31:24 -0600 Subject: [llvm-commits] CVS: llvm/examples/BFtoLLVM/BFtoLLVM.cpp Message-ID: <200603030131.TAA03484@zion.cs.uiuc.edu> Changes in directory llvm/examples/BFtoLLVM: BFtoLLVM.cpp updated: 1.3 -> 1.4 --- Log message: Upgrade this to use the new intrinsic names --- Diffs of the changes: (+3 -2) BFtoLLVM.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/examples/BFtoLLVM/BFtoLLVM.cpp diff -u llvm/examples/BFtoLLVM/BFtoLLVM.cpp:1.3 llvm/examples/BFtoLLVM/BFtoLLVM.cpp:1.4 --- llvm/examples/BFtoLLVM/BFtoLLVM.cpp:1.3 Thu Apr 21 22:18:57 2005 +++ llvm/examples/BFtoLLVM/BFtoLLVM.cpp Thu Mar 2 19:31:12 2006 @@ -29,7 +29,7 @@ << "\n; Declarations\n" << "\ndeclare int %getchar()\n" << "declare int %putchar(int)\n" - << "declare void %llvm.memset(sbyte*, ubyte, uint, uint)\n" + << "declare void %llvm.memset.i32(sbyte*, ubyte, uint, uint)\n" << "\n"; } @@ -38,7 +38,8 @@ << "int %main(int %argc, sbyte** %argv) {\n" << "\nentry:\n" << "%arr = alloca sbyte, uint 30000\n" - << "call void (sbyte*, ubyte, uint, uint)* %llvm.memset(sbyte* %arr, ubyte 0, uint 30000, uint 1)\n" + << "call void (sbyte*, ubyte, uint, uint)* %llvm.memset.i32" + << "(sbyte* %arr, ubyte 0, uint 30000, uint 1)\n" << "%ptrbox = alloca sbyte*\n" << "store sbyte* %arr, sbyte **%ptrbox\n" << "\n"; From lattner at cs.uiuc.edu Thu Mar 2 19:34:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:34:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200603030134.TAA03528@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.446 -> 1.447 --- Log message: Change this to work with renamed intrinsics. --- Diffs of the changes: (+7 -1) InstructionCombining.cpp | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.446 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.447 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.446 Thu Mar 2 00:50:58 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Mar 2 19:34:17 2006 @@ -5286,7 +5286,13 @@ if (GlobalVariable *GVSrc = dyn_cast(MMI->getSource())) if (GVSrc->isConstant()) { Module *M = CI.getParent()->getParent()->getParent(); - Function *MemCpy = M->getOrInsertFunction("llvm.memcpy", + const char *Name; + if (CI.getCalledFunction()->getFunctionType()->getParamType(3) == + Type::UIntTy) + Name = "llvm.memcpy.i32"; + else + Name = "llvm.memcpy.i64"; + Function *MemCpy = M->getOrInsertFunction(Name, CI.getCalledFunction()->getFunctionType()); CI.setOperand(0, MemCpy); Changed = true; From lattner at cs.uiuc.edu Thu Mar 2 19:47:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:47:25 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l TableGen.cpp Message-ID: <200603030147.TAA03621@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.26 -> 1.27 TableGen.cpp updated: 1.42 -> 1.43 --- Log message: add support for multiple include directories --- Diffs of the changes: (+16 -12) FileLexer.l | 18 +++++++++++------- TableGen.cpp | 10 +++++----- 2 files changed, 16 insertions(+), 12 deletions(-) Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.26 llvm/utils/TableGen/FileLexer.l:1.27 --- llvm/utils/TableGen/FileLexer.l:1.26 Mon Feb 13 23:13:13 2006 +++ llvm/utils/TableGen/FileLexer.l Thu Mar 2 19:47:14 2006 @@ -36,7 +36,7 @@ namespace llvm { // Global variable recording the location of the include directory -std::string IncludeDirectory; +std::vector IncludeDirectories; /// ParseInt - This has to handle the special case of binary numbers 0b0101 /// @@ -74,7 +74,8 @@ /// ParseFile - this function begins the parsing of the specified tablegen file. /// -void ParseFile(const std::string &Filename, const std::string & IncludeDir) { +void ParseFile(const std::string &Filename, + const std::vector &IncludeDirs) { FILE *F = stdin; if (Filename != "-") { F = fopen(Filename.c_str(), "r"); @@ -90,7 +91,7 @@ // Record the location of the include directory so that the lexer can find // it later. - IncludeDirectory = IncludeDir; + IncludeDirectories = IncludeDirs; Filein = F; Filelineno = 1; @@ -124,10 +125,13 @@ // If we couldn't find the file in the current directory, look for it in // the include directories. // - // NOTE: Right now, there is only one directory. We need to eventually add - // support for more. - std::string NextFilename = IncludeDirectory + "/" + Filename; - yyin = fopen(NextFilename.c_str(), "r"); + std::string NextFilename; + for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) { + NextFilename = IncludeDirectories[i] + "/" + Filename; + if (yyin = fopen(NextFilename.c_str(), "r")) + break; + } + if (yyin == 0) { err() << "Could not find include file '" << Filename << "'!\n"; exit(1); Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.42 llvm/utils/TableGen/TableGen.cpp:1.43 --- llvm/utils/TableGen/TableGen.cpp:1.42 Sun Dec 25 23:08:55 2005 +++ llvm/utils/TableGen/TableGen.cpp Thu Mar 2 19:47:14 2006 @@ -82,14 +82,14 @@ cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); - cl::opt - IncludeDir("I", cl::desc("Directory of include files"), - cl::value_desc("directory"), cl::init("")); + cl::list + IncludeDirs("I", cl::desc("Directory of include files"), + cl::value_desc("directory")); } namespace llvm { void ParseFile(const std::string &Filename, - const std::string &IncludeDir); + const std::vector &IncludeDirs); } RecordKeeper llvm::Records; @@ -420,7 +420,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); - ParseFile(InputFilename, IncludeDir); + ParseFile(InputFilename, IncludeDirs); std::ostream *Out = &std::cout; if (OutputFilename != "-") { From lattner at cs.uiuc.edu Thu Mar 2 19:47:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:47:49 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.cpp.cvs FileLexer.l.cvs Message-ID: <200603030147.TAA03659@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.cpp.cvs updated: 1.2 -> 1.3 FileLexer.l.cvs updated: 1.1 -> 1.2 --- Log message: Regenerate --- Diffs of the changes: (+62 -54) FileLexer.cpp.cvs | 98 ++++++++++++++++++++++++++++-------------------------- FileLexer.l.cvs | 18 ++++++--- 2 files changed, 62 insertions(+), 54 deletions(-) Index: llvm/utils/TableGen/FileLexer.cpp.cvs diff -u llvm/utils/TableGen/FileLexer.cpp.cvs:1.2 llvm/utils/TableGen/FileLexer.cpp.cvs:1.3 --- llvm/utils/TableGen/FileLexer.cpp.cvs:1.2 Wed Feb 15 01:24:01 2006 +++ llvm/utils/TableGen/FileLexer.cpp.cvs Thu Mar 2 19:47:37 2006 @@ -21,7 +21,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /var/cvs/llvm/llvm/utils/TableGen/FileLexer.cpp.cvs,v 1.2 2006/02/15 07:24:01 lattner Exp $ + * $Header: /var/cvs/llvm/llvm/utils/TableGen/FileLexer.cpp.cvs,v 1.3 2006/03/03 01:47:37 lattner Exp $ */ #define FLEX_SCANNER @@ -489,7 +489,7 @@ #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 1 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" #define INITIAL 0 /*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===// // @@ -507,7 +507,7 @@ #define YY_NEVER_INTERACTIVE 1 #define comment 1 -#line 30 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 30 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" #include "Record.h" typedef std::pair*> SubClassRefTy; #include "FileParser.h" @@ -517,7 +517,7 @@ namespace llvm { // Global variable recording the location of the include directory -std::string IncludeDirectory; +std::vector IncludeDirectories; /// ParseInt - This has to handle the special case of binary numbers 0b0101 /// @@ -555,7 +555,8 @@ /// ParseFile - this function begins the parsing of the specified tablegen file. /// -void ParseFile(const std::string &Filename, const std::string & IncludeDir) { +void ParseFile(const std::string &Filename, + const std::vector &IncludeDirs) { FILE *F = stdin; if (Filename != "-") { F = fopen(Filename.c_str(), "r"); @@ -571,7 +572,7 @@ // Record the location of the include directory so that the lexer can find // it later. - IncludeDirectory = IncludeDir; + IncludeDirectories = IncludeDirs; Filein = F; Filelineno = 1; @@ -605,10 +606,13 @@ // If we couldn't find the file in the current directory, look for it in // the include directories. // - // NOTE: Right now, there is only one directory. We need to eventually add - // support for more. - std::string NextFilename = IncludeDirectory + "/" + Filename; - yyin = fopen(NextFilename.c_str(), "r"); + std::string NextFilename; + for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) { + NextFilename = IncludeDirectories[i] + "/" + Filename; + if (yyin = fopen(NextFilename.c_str(), "r")) + break; + } + if (yyin == 0) { err() << "Could not find include file '" << Filename << "'!\n"; exit(1); @@ -644,7 +648,7 @@ using namespace llvm; -#line 648 "Lexer.cpp" +#line 652 "Lexer.cpp" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -795,10 +799,10 @@ register char *yy_cp, *yy_bp; register int yy_act; -#line 176 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 180 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" -#line 802 "Lexer.cpp" +#line 806 "Lexer.cpp" if ( yy_init ) { @@ -891,168 +895,168 @@ { /* beginning of action switch */ case 1: YY_RULE_SETUP -#line 178 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 182 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { /* Ignore comments */ } YY_BREAK case 2: YY_RULE_SETUP -#line 180 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 184 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { HandleInclude(yytext); } YY_BREAK case 3: YY_RULE_SETUP -#line 181 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 185 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2); return CODEFRAGMENT; } YY_BREAK case 4: YY_RULE_SETUP -#line 184 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 188 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return INT; } YY_BREAK case 5: YY_RULE_SETUP -#line 185 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 189 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return BIT; } YY_BREAK case 6: YY_RULE_SETUP -#line 186 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 190 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return BITS; } YY_BREAK case 7: YY_RULE_SETUP -#line 187 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 191 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return STRING; } YY_BREAK case 8: YY_RULE_SETUP -#line 188 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 192 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return LIST; } YY_BREAK case 9: YY_RULE_SETUP -#line 189 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 193 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return CODE; } YY_BREAK case 10: YY_RULE_SETUP -#line 190 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 194 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return DAG; } YY_BREAK case 11: YY_RULE_SETUP -#line 192 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 196 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return CLASS; } YY_BREAK case 12: YY_RULE_SETUP -#line 193 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 197 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return DEF; } YY_BREAK case 13: YY_RULE_SETUP -#line 194 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 198 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return FIELD; } YY_BREAK case 14: YY_RULE_SETUP -#line 195 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 199 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return LET; } YY_BREAK case 15: YY_RULE_SETUP -#line 196 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 200 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return IN; } YY_BREAK case 16: YY_RULE_SETUP -#line 198 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 202 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return SRATOK; } YY_BREAK case 17: YY_RULE_SETUP -#line 199 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 203 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return SRLTOK; } YY_BREAK case 18: YY_RULE_SETUP -#line 200 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 204 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return SHLTOK; } YY_BREAK case 19: YY_RULE_SETUP -#line 203 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 207 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext, yytext+yyleng); return ID; } YY_BREAK case 20: YY_RULE_SETUP -#line 205 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 209 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng); return VARNAME; } YY_BREAK case 21: YY_RULE_SETUP -#line 208 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 212 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1); return STRVAL; } YY_BREAK case 22: YY_RULE_SETUP -#line 211 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 215 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { Filelval.IntVal = ParseInt(Filetext); return INTVAL; } YY_BREAK case 23: YY_RULE_SETUP -#line 213 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 217 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { /* Ignore whitespace */ } YY_BREAK case 24: YY_RULE_SETUP -#line 216 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 220 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { BEGIN(comment); CommentDepth++; } YY_BREAK case 25: YY_RULE_SETUP -#line 217 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 221 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" {} /* eat anything that's not a '*' or '/' */ YY_BREAK case 26: YY_RULE_SETUP -#line 218 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 222 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" {} /* eat up '*'s not followed by '/'s */ YY_BREAK case 27: YY_RULE_SETUP -#line 219 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 223 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { ++CommentDepth; } YY_BREAK case 28: YY_RULE_SETUP -#line 220 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 224 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" {} /* eat up /'s not followed by *'s */ YY_BREAK case 29: YY_RULE_SETUP -#line 221 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 225 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { if (!--CommentDepth) { BEGIN(INITIAL); } } YY_BREAK case YY_STATE_EOF(comment): -#line 222 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 226 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { err() << "Unterminated comment!\n"; exit(1); } YY_BREAK case 30: YY_RULE_SETUP -#line 224 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 228 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" { return Filetext[0]; } YY_BREAK case 31: YY_RULE_SETUP -#line 226 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 230 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1056 "Lexer.cpp" +#line 1060 "Lexer.cpp" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1936,6 +1940,6 @@ return 0; } #endif -#line 226 "/Users/sabre/cvs/llvm/utils/TableGen/FileLexer.l" +#line 230 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileLexer.l" Index: llvm/utils/TableGen/FileLexer.l.cvs diff -u llvm/utils/TableGen/FileLexer.l.cvs:1.1 llvm/utils/TableGen/FileLexer.l.cvs:1.2 --- llvm/utils/TableGen/FileLexer.l.cvs:1.1 Mon Feb 13 23:13:13 2006 +++ llvm/utils/TableGen/FileLexer.l.cvs Thu Mar 2 19:47:37 2006 @@ -36,7 +36,7 @@ namespace llvm { // Global variable recording the location of the include directory -std::string IncludeDirectory; +std::vector IncludeDirectories; /// ParseInt - This has to handle the special case of binary numbers 0b0101 /// @@ -74,7 +74,8 @@ /// ParseFile - this function begins the parsing of the specified tablegen file. /// -void ParseFile(const std::string &Filename, const std::string & IncludeDir) { +void ParseFile(const std::string &Filename, + const std::vector &IncludeDirs) { FILE *F = stdin; if (Filename != "-") { F = fopen(Filename.c_str(), "r"); @@ -90,7 +91,7 @@ // Record the location of the include directory so that the lexer can find // it later. - IncludeDirectory = IncludeDir; + IncludeDirectories = IncludeDirs; Filein = F; Filelineno = 1; @@ -124,10 +125,13 @@ // If we couldn't find the file in the current directory, look for it in // the include directories. // - // NOTE: Right now, there is only one directory. We need to eventually add - // support for more. - std::string NextFilename = IncludeDirectory + "/" + Filename; - yyin = fopen(NextFilename.c_str(), "r"); + std::string NextFilename; + for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) { + NextFilename = IncludeDirectories[i] + "/" + Filename; + if (yyin = fopen(NextFilename.c_str(), "r")) + break; + } + if (yyin == 0) { err() << "Could not find include file '" << Filename << "'!\n"; exit(1); From lattner at cs.uiuc.edu Thu Mar 2 19:53:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:53:52 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200603030153.TAA03705@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.43 -> 1.44 --- Log message: Add support for "-Ifoo" in addition to "-I foo" --- Diffs of the changes: (+1 -1) TableGen.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.43 llvm/utils/TableGen/TableGen.cpp:1.44 --- llvm/utils/TableGen/TableGen.cpp:1.43 Thu Mar 2 19:47:14 2006 +++ llvm/utils/TableGen/TableGen.cpp Thu Mar 2 19:53:40 2006 @@ -84,7 +84,7 @@ cl::list IncludeDirs("I", cl::desc("Directory of include files"), - cl::value_desc("directory")); + cl::value_desc("directory"), cl::Prefix); } namespace llvm { From lattner at cs.uiuc.edu Thu Mar 2 19:54:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:54:23 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.td Message-ID: <200603030154.TAA03767@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.td added (r1.1) --- Log message: Split this out of Target.td --- Diffs of the changes: (+45 -0) ValueTypes.td | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 45 insertions(+) Index: llvm/include/llvm/CodeGen/ValueTypes.td diff -c /dev/null llvm/include/llvm/CodeGen/ValueTypes.td:1.1 *** /dev/null Thu Mar 2 19:54:21 2006 --- llvm/include/llvm/CodeGen/ValueTypes.td Thu Mar 2 19:54:11 2006 *************** *** 0 **** --- 1,45 ---- + //===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Value types - These values correspond to the register types defined in the + // ValueTypes.h file. If you update anything here, you must update it there as + // well! + // + //===----------------------------------------------------------------------===// + + class ValueType { + string Namespace = "MVT"; + int Size = size; + int Value = value; + } + + def OtherVT: ValueType<0 , 0>; // "Other" value + def i1 : ValueType<1 , 1>; // One bit boolean value + def i8 : ValueType<8 , 2>; // 8-bit integer value + def i16 : ValueType<16 , 3>; // 16-bit integer value + def i32 : ValueType<32 , 4>; // 32-bit integer value + def i64 : ValueType<64 , 5>; // 64-bit integer value + def i128 : ValueType<128, 6>; // 128-bit integer value + def f32 : ValueType<32 , 7>; // 32-bit floating point value + def f64 : ValueType<64 , 8>; // 64-bit floating point value + def f80 : ValueType<80 , 9>; // 80-bit floating point value + def f128 : ValueType<128, 10>; // 128-bit floating point value + def FlagVT : ValueType<0 , 11>; // Condition code or machine flag + def isVoid : ValueType<0 , 12>; // Produces no value + def Vector : ValueType<0 , 13>; // Abstract vector value + def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value + def v4i16 : ValueType<64 , 15>; // 4 x i16 vector value + def v2i32 : ValueType<64 , 16>; // 2 x i32 vector value + def v16i8 : ValueType<128, 17>; // 16 x i8 vector value + def v8i16 : ValueType<128, 18>; // 8 x i16 vector value + def v4i32 : ValueType<128, 19>; // 4 x i32 vector value + def v2i64 : ValueType<128, 20>; // 2 x i64 vector value + def v2f32 : ValueType<64, 21>; // 2 x f32 vector value + def v4f32 : ValueType<128, 22>; // 4 x f32 vector value + def v2f64 : ValueType<128, 23>; // 2 x f64 vector value From lattner at cs.uiuc.edu Thu Mar 2 19:55:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:55:06 -0600 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200603030155.TAA03834@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.348 -> 1.349 --- Log message: pass -Illvm/include to tblgen --- Diffs of the changes: (+3 -2) Makefile.rules | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.348 llvm/Makefile.rules:1.349 --- llvm/Makefile.rules:1.348 Tue Feb 28 13:12:58 2006 +++ llvm/Makefile.rules Thu Mar 2 19:54:54 2006 @@ -378,7 +378,7 @@ ProgInstall = $(INSTALL) $(Install.StripFlag) -m 0755 DataInstall = $(INSTALL) -m 0644 Burg = $(BURG) -I $(PROJ_SRC_DIR) -TableGen = $(TBLGEN) -I $(PROJ_SRC_DIR) +TableGen = $(TBLGEN) -I $(PROJ_SRC_DIR) -I$(PROJ_SRC_ROOT)/include Archive = $(AR) $(AR.Flags) LArchive = $(LLVMToolDir)/llvm-ar rcsf ifdef RANLIB @@ -1120,7 +1120,8 @@ TDFiles := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td) \ $(LLVM_SRC_ROOT)/lib/Target/Target.td \ - $(LLVM_SRC_ROOT)/lib/Target/TargetSelectionDAG.td) + $(LLVM_SRC_ROOT)/lib/Target/TargetSelectionDAG.td \ + $(LLVM_SRC_ROOT)/include/llvm/CodeGen/ValueTypes.td) INCFiles := $(filter %.inc,$(BUILT_SOURCES)) INCTMPFiles := $(INCFiles:%=$(ObjDir)/%.tmp) .PRECIOUS: $(INCTMPFiles) $(INCFiles) From lattner at cs.uiuc.edu Thu Mar 2 19:55:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:55:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200603030155.TAA03896@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.72 -> 1.73 --- Log message: Split the valuetypes out of Target.td into ValueTypes.td --- Diffs of the changes: (+1 -37) Target.td | 38 +------------------------------------- 1 files changed, 1 insertion(+), 37 deletions(-) Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.72 llvm/lib/Target/Target.td:1.73 --- llvm/lib/Target/Target.td:1.72 Tue Feb 28 19:06:22 2006 +++ llvm/lib/Target/Target.td Thu Mar 2 19:55:26 2006 @@ -12,43 +12,7 @@ // //===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// -// Value types - These values correspond to the register types defined in the -// ValueTypes.h file. If you update anything here, you must update it there as -// well! -// -class ValueType { - string Namespace = "MVT"; - int Size = size; - int Value = value; -} - -def OtherVT: ValueType<0 , 0>; // "Other" value -def i1 : ValueType<1 , 1>; // One bit boolean value -def i8 : ValueType<8 , 2>; // 8-bit integer value -def i16 : ValueType<16 , 3>; // 16-bit integer value -def i32 : ValueType<32 , 4>; // 32-bit integer value -def i64 : ValueType<64 , 5>; // 64-bit integer value -def i128 : ValueType<128, 6>; // 128-bit integer value -def f32 : ValueType<32 , 7>; // 32-bit floating point value -def f64 : ValueType<64 , 8>; // 64-bit floating point value -def f80 : ValueType<80 , 9>; // 80-bit floating point value -def f128 : ValueType<128, 10>; // 128-bit floating point value -def FlagVT : ValueType<0 , 11>; // Condition code or machine flag -def isVoid : ValueType<0 , 12>; // Produces no value -def Vector : ValueType<0 , 13>; // Abstract vector value -def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value -def v4i16 : ValueType<64 , 15>; // 4 x i16 vector value -def v2i32 : ValueType<64 , 16>; // 2 x i32 vector value -def v16i8 : ValueType<128, 17>; // 16 x i8 vector value -def v8i16 : ValueType<128, 18>; // 8 x i16 vector value -def v4i32 : ValueType<128, 19>; // 4 x i32 vector value -def v2i64 : ValueType<128, 20>; // 2 x i64 vector value -def v2f32 : ValueType<64, 21>; // 2 x f32 vector value -def v4f32 : ValueType<128, 22>; // 4 x f32 vector value -def v2f64 : ValueType<128, 23>; // 2 x f64 vector value +include "llvm/CodeGen/ValueTypes.td" //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target From lattner at cs.uiuc.edu Thu Mar 2 19:56:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 19:56:01 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200603030156.TAA03957@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.20 -> 1.21 --- Log message: update comment --- Diffs of the changes: (+1 -1) ValueTypes.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.20 llvm/include/llvm/CodeGen/ValueTypes.h:1.21 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.20 Tue Feb 28 18:55:26 2006 +++ llvm/include/llvm/CodeGen/ValueTypes.h Thu Mar 2 19:55:49 2006 @@ -27,7 +27,7 @@ /// namespace MVT { // MVT = Machine Value Types enum ValueType { - // If you change this numbering, you must change the values in Target.td as + // If you change this numbering, you must change the values in ValueTypes.td // well! Other = 0, // This is a non-standard value i1 = 1, // This is a 1 bit integer value From lattner at cs.uiuc.edu Thu Mar 2 20:04:19 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 20:04:19 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/SubtargetEmitter.cpp Message-ID: <200603030204.UAA04075@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: SubtargetEmitter.cpp updated: 1.17 -> 1.18 --- Log message: remove out of date comment --- Diffs of the changes: (+1 -2) SubtargetEmitter.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/utils/TableGen/SubtargetEmitter.cpp diff -u llvm/utils/TableGen/SubtargetEmitter.cpp:1.17 llvm/utils/TableGen/SubtargetEmitter.cpp:1.18 --- llvm/utils/TableGen/SubtargetEmitter.cpp:1.17 Fri Jan 27 02:09:42 2006 +++ llvm/utils/TableGen/SubtargetEmitter.cpp Thu Mar 2 20:04:07 2006 @@ -7,8 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This tablegen backend emits subtarget enumerations. The format is in a state -// flux and will be tightened up when integration to scheduling is complete. +// This tablegen backend emits subtarget enumerations. // //===----------------------------------------------------------------------===// From evan.cheng at apple.com Thu Mar 2 20:04:40 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 2 Mar 2006 20:04:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200603030204.UAA04085@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.56 -> 1.57 --- Log message: Move #include "llvm/CodeGen/AsmPrinter.h" to top since it's the interface. --- Diffs of the changes: (+1 -1) AsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.56 llvm/lib/CodeGen/AsmPrinter.cpp:1.57 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.56 Wed Mar 1 16:18:09 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Thu Mar 2 20:04:29 2006 @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Assembly/Writer.h" #include "llvm/DerivedTypes.h" -#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Constants.h" #include "llvm/Module.h" #include "llvm/CodeGen/MachineConstantPool.h" From bocchino at persephone.cs.uiuc.edu Thu Mar 2 20:12:26 2006 From: bocchino at persephone.cs.uiuc.edu (Robert L. Bocchino Jr.) Date: Thu, 2 Mar 2006 20:12:26 -0600 (CST) Subject: [llvm-commits] CVS: llvm/tools/analyze/analyze.cpp Message-ID: <20060303021226.10674201C211@persephone.cs.uiuc.edu> Changes in directory llvm/tools/analyze: analyze.cpp updated: 1.65 -> 1.66 --- Log message: Implemented -quiet feature for analyze --- Diffs of the changes: (+35 -30) analyze.cpp | 65 ++++++++++++++++++++++++++++++++---------------------------- 1 files changed, 35 insertions(+), 30 deletions(-) Index: llvm/tools/analyze/analyze.cpp diff -u llvm/tools/analyze/analyze.cpp:1.65 llvm/tools/analyze/analyze.cpp:1.66 --- llvm/tools/analyze/analyze.cpp:1.65 Sun Oct 23 20:00:13 2005 +++ llvm/tools/analyze/analyze.cpp Thu Mar 2 20:12:04 2006 @@ -31,13 +31,36 @@ using namespace llvm; +namespace { + cl::opt + InputFilename(cl::Positional, cl::desc(""), cl::init("-"), + cl::value_desc("filename")); + + cl::opt Quiet("q", cl::desc("Don't print analysis pass names")); + cl::alias QuietA("quiet", cl::desc("Alias for -q"), + cl::aliasopt(Quiet)); + + cl::opt NoVerify("disable-verify", cl::Hidden, + cl::desc("Do not verify input module")); + + // The AnalysesList is automatically populated with registered Passes by the + // PassNameParser. + // + cl::list > + AnalysesList(cl::desc("Analyses available:")); + + Timer BytecodeLoadTimer("Bytecode Loader"); +} + struct ModulePassPrinter : public ModulePass { const PassInfo *PassToPrint; ModulePassPrinter(const PassInfo *PI) : PassToPrint(PI) {} virtual bool runOnModule(Module &M) { - std::cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - getAnalysisID(PassToPrint).print(std::cout, &M); + if (!Quiet) { + std::cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + getAnalysisID(PassToPrint).print(std::cout, &M); + } // Get and print pass... return false; @@ -56,11 +79,12 @@ FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {} virtual bool runOnFunction(Function &F) { - std::cout << "Printing analysis '" << PassToPrint->getPassName() - << "' for function '" << F.getName() << "':\n"; - getAnalysisID(PassToPrint).print(std::cout, F.getParent()); - + if (!Quiet) { + std::cout << "Printing analysis '" << PassToPrint->getPassName() + << "' for function '" << F.getName() << "':\n"; + } // Get and print pass... + getAnalysisID(PassToPrint).print(std::cout, F.getParent()); return false; } @@ -77,11 +101,13 @@ BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {} virtual bool runOnBasicBlock(BasicBlock &BB) { - std::cout << "Printing Analysis info for BasicBlock '" << BB.getName() - << "': Pass " << PassToPrint->getPassName() << ":\n"; - getAnalysisID(PassToPrint).print(std::cout, BB.getParent()->getParent()); + if (!Quiet) { + std::cout << "Printing Analysis info for BasicBlock '" << BB.getName() + << "': Pass " << PassToPrint->getPassName() << ":\n"; + } // Get and print pass... + getAnalysisID(PassToPrint).print(std::cout, BB.getParent()->getParent()); return false; } @@ -95,27 +121,6 @@ -namespace { - cl::opt - InputFilename(cl::Positional, cl::desc(""), cl::init("-"), - cl::value_desc("filename")); - - cl::opt Quiet("q", cl::desc("Don't print analysis pass names")); - cl::alias QuietA("quiet", cl::desc("Alias for -q"), - cl::aliasopt(Quiet)); - - cl::opt NoVerify("disable-verify", cl::Hidden, - cl::desc("Do not verify input module")); - - // The AnalysesList is automatically populated with registered Passes by the - // PassNameParser. - // - cl::list > - AnalysesList(cl::desc("Analyses available:")); - - Timer BytecodeLoadTimer("Bytecode Loader"); -} - int main(int argc, char **argv) { try { cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n"); From lattner at cs.uiuc.edu Thu Mar 2 20:32:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 20:32:58 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenIntrinsics.h IntrinsicEmitter.cpp IntrinsicEmitter.h TableGen.cpp Message-ID: <200603030232.UAA04288@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenIntrinsics.h added (r1.1) IntrinsicEmitter.cpp added (r1.1) IntrinsicEmitter.h added (r1.1) TableGen.cpp updated: 1.44 -> 1.45 --- Log message: initial implementation of intrinsic parsing --- Diffs of the changes: (+157 -0) CodeGenIntrinsics.h | 42 ++++++++++++++++++++++++++++++ IntrinsicEmitter.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ IntrinsicEmitter.h | 38 +++++++++++++++++++++++++++ TableGen.cpp | 7 +++++ 4 files changed, 157 insertions(+) Index: llvm/utils/TableGen/CodeGenIntrinsics.h diff -c /dev/null llvm/utils/TableGen/CodeGenIntrinsics.h:1.1 *** /dev/null Thu Mar 2 20:32:56 2006 --- llvm/utils/TableGen/CodeGenIntrinsics.h Thu Mar 2 20:32:46 2006 *************** *** 0 **** --- 1,42 ---- + //===- CodeGenIntrinsic.h - Intrinsic Class Wrapper ------------*- C++ -*--===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines a wrapper class for the 'Intrinsic' TableGen class. + // + //===----------------------------------------------------------------------===// + + #ifndef CODEGEN_INTRINSIC_H + #define CODEGEN_INTRINSIC_H + + #include + #include + + namespace llvm { + class Record; + class RecordKeeper; + + struct CodeGenIntrinsic { + Record *TheDef; // The actual record defining this instruction. + std::string Name; // The name of the LLVM function "llvm.bswap.i32" + std::string EnumName; // The name of the enum "bswap_i32" + + // Memory mod/ref behavior of this intrinsic. + enum { + NoMem, ReadArgMem, ReadMem, WriteArgMem, WriteMem + } ModRef; + + CodeGenIntrinsic(Record *R); + }; + + /// LoadIntrinsics - Read all of the intrinsics defined in the specified + /// .td file. + std::vector LoadIntrinsics(const RecordKeeper &RC); + } + + #endif Index: llvm/utils/TableGen/IntrinsicEmitter.cpp diff -c /dev/null llvm/utils/TableGen/IntrinsicEmitter.cpp:1.1 *** /dev/null Thu Mar 2 20:32:58 2006 --- llvm/utils/TableGen/IntrinsicEmitter.cpp Thu Mar 2 20:32:46 2006 *************** *** 0 **** --- 1,70 ---- + //===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This tablegen backend emits information about intrinsic functions. + // + //===----------------------------------------------------------------------===// + + #include "IntrinsicEmitter.h" + #include "Record.h" + using namespace llvm; + + //===----------------------------------------------------------------------===// + // CodeGenIntrinsic Implementation + //===----------------------------------------------------------------------===// + + std::vector llvm::LoadIntrinsics(const RecordKeeper &RC) { + std::vector I = RC.getAllDerivedDefinitions("Intrinsic"); + return std::vector(I.begin(), I.end()); + } + + CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { + std::string DefName = R->getName(); + + if (DefName.size() <= 4 || + std::string(DefName.begin(), DefName.begin()+4) != "int_") + throw "Intrinsic '" + DefName + "' does not start with 'int_'!"; + EnumName = std::string(DefName.begin()+4, DefName.end()); + + Name = R->getValueAsString("LLVMName"); + if (Name == "") { + // If an explicit name isn't specified, derive one from the DefName. + Name = "llvm."; + for (unsigned i = 0, e = EnumName.size(); i != e; ++i) + if (EnumName[i] == '_') + Name += '.'; + else + Name += EnumName[i]; + } + } + + //===----------------------------------------------------------------------===// + // IntrinsicEmitter Implementation + //===----------------------------------------------------------------------===// + + void IntrinsicEmitter::run(std::ostream &OS) { + EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); + + std::vector Ints = LoadIntrinsics(Records); + + // Emit the enum information. + EmitEnumInfo(Ints, OS); + } + + void IntrinsicEmitter::EmitEnumInfo(const std::vector &Ints, + std::ostream &OS) { + OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; + for (unsigned i = 0, e = Ints.size(); i != e; ++i) { + OS << " " << Ints[i].EnumName; + OS << ((i != e-1) ? ", " : " "); + OS << std::string(40-Ints[i].EnumName.size(), ' ') + << "// " << Ints[i].Name << "\n"; + } + OS << "#endif\n\n"; + } Index: llvm/utils/TableGen/IntrinsicEmitter.h diff -c /dev/null llvm/utils/TableGen/IntrinsicEmitter.h:1.1 *** /dev/null Thu Mar 2 20:32:58 2006 --- llvm/utils/TableGen/IntrinsicEmitter.h Thu Mar 2 20:32:46 2006 *************** *** 0 **** --- 1,38 ---- + //===- IntrinsicEmitter.h - Generate intrinsic information ------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This tablegen backend emits information about intrinsic functions. + // + //===----------------------------------------------------------------------===// + + #ifndef INTRINSIC_EMITTER_H + #define INTRINSIC_EMITTER_H + + #include "CodeGenIntrinsics.h" + #include "TableGenBackend.h" + + namespace llvm { + class IntrinsicEmitter : public TableGenBackend { + RecordKeeper &Records; + + public: + IntrinsicEmitter(RecordKeeper &R) : Records(R) {} + + void run(std::ostream &OS); + + void EmitEnumInfo(const std::vector &Ints, + std::ostream &OS); + }; + + } // End llvm namespace + + #endif + + + Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.44 llvm/utils/TableGen/TableGen.cpp:1.45 --- llvm/utils/TableGen/TableGen.cpp:1.44 Thu Mar 2 19:53:40 2006 +++ llvm/utils/TableGen/TableGen.cpp Thu Mar 2 20:32:46 2006 @@ -25,6 +25,7 @@ #include "AsmWriterEmitter.h" #include "DAGISelEmitter.h" #include "SubtargetEmitter.h" +#include "IntrinsicEmitter.h" #include #include #include @@ -38,6 +39,7 @@ GenInstrEnums, GenInstrs, GenAsmWriter, GenDAGISel, GenSubtarget, + GenIntrinsic, PrintEnums, Parse }; @@ -65,6 +67,8 @@ "Generate a DAG instruction selector"), clEnumValN(GenSubtarget, "gen-subtarget", "Generate subtarget enumerations"), + clEnumValN(GenIntrinsic, "gen-intrinsic", + "Generate intrinsic information"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(Parse, "parse", @@ -474,6 +478,9 @@ case GenSubtarget: SubtargetEmitter(Records).run(*Out); break; + case GenIntrinsic: + IntrinsicEmitter(Records).run(*Out); + break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); From lattner at cs.uiuc.edu Thu Mar 2 20:33:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 20:33:27 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.td Message-ID: <200603030233.UAA04349@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.td added (r1.1) --- Log message: initial checkin of the intrinsic description file --- Diffs of the changes: (+188 -0) Intrinsics.td | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 188 insertions(+) Index: llvm/include/llvm/Intrinsics.td diff -c /dev/null llvm/include/llvm/Intrinsics.td:1.1 *** /dev/null Thu Mar 2 20:33:25 2006 --- llvm/include/llvm/Intrinsics.td Thu Mar 2 20:33:15 2006 *************** *** 0 **** --- 1,188 ---- + //===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines properties of all LLVM intrinsics. + // + //===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// + // Properties we keep track of for intrinsics. + //===----------------------------------------------------------------------===// + + class IntrinsicProperty; + + // Intr*Mem - Memory properties. An intrinsic is allowed to have exactly one of + // these properties set. They are listed from the most aggressive (best to use + // if correct) to the least aggressive. If no property is set, the worst case + // is assumed (IntrWriteMem). + + // InstrNoMem - The intrinsic does not access memory or have any other side + // effects. It may be CSE'd deleted if dead, etc. + def InstrNoMem : IntrinsicProperty; + + // InstrReadArgMem - This intrinsic reads only from memory that one of its + // arguments points to, but may read an unspecified amount. + def InstrReadArgMem : IntrinsicProperty; + + // IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be + // moved across stores. However, it can be reordered otherwise and can be + // deleted if dead. + def IntrReadMem : IntrinsicProperty; + + // InstrWriteArgMem - This intrinsic reads and writes only from memory that one + // of its arguments points to, but may access an unspecified amount. It has no + // other side effects. This may only be used if the intrinsic doesn't "capture" + // the argument pointer (e.g. storing it someplace). + def InstrWriteArgMem : IntrinsicProperty; + + // IntrWriteMem - This intrinsic may read or modify unspecified memory or has + // other side effects. It cannot be modified by the optimizer. This is the + // default if the intrinsic has no other Intr*Mem property. + def IntrWriteMem : IntrinsicProperty; + + //===----------------------------------------------------------------------===// + // Types used by intrinsics. + //===----------------------------------------------------------------------===// + + class LLVMType { + string TypeVal = typeval; + } + + def llvm_void_ty : LLVMType<"Type::VoidTyID">; + def llvm_bool_ty : LLVMType<"Type::BoolTyID">; + def llvm_sbyte_ty : LLVMType<"Type::SByteTyID">; + def llvm_short_ty : LLVMType<"Type::ShortTyID">; + def llvm_int_ty : LLVMType<"Type::IntTyID">; + def llvm_long_ty : LLVMType<"Type::LongTyID">; + def llvm_ubyte_ty : LLVMType<"Type::UByteTyID">; + def llvm_ushort_ty : LLVMType<"Type::UShortTyID">; + def llvm_uint_ty : LLVMType<"Type::UIntTyID">; + def llvm_ulong_ty : LLVMType<"Type::ULongTyID">; + def llvm_float_ty : LLVMType<"Type::FloatTyID">; + def llvm_double_ty : LLVMType<"Type::DoubleTyID">; + def llvm_ptr_ty : LLVMType<"Type::PointerTyID">; // sbyte* + def llvm_ptrptr_ty : LLVMType<"Type::PointerTyID">; // sbyte** + def llvm_anchor_ty : LLVMType<"Type::PointerTyID">; // {}* + def llvm_descriptor_ty : LLVMType<"Type::PointerTyID">; // global* + + //===----------------------------------------------------------------------===// + // Intrinsic Definitions. + //===----------------------------------------------------------------------===// + + // Intrinsic class - This is used to define one LLVM intrinsic. The name of the + // intrinsic definition should start with "int_", then match the LLVM intrinsic + // name with the "llvm." prefix removed, and all "."s turned into "_"s. For + // example, llvm.bswap.i16 -> int_bswap_i16. + // + // * Types is a list containing the return type and the argument types + // expected for the intrinsic. + // * Properties can be set to describe the behavior of the intrinsic. + // + class Intrinsic types, + list properties = [], + string name = ""> { + string LLVMName = name; + list Types = types; + list Properties = properties; + } + + + //===--------------- Variable Argument Handling Intrinsics ----------------===// + // + + def int_vastart : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty], [], "llvm.va_start">; + def int_vacopy : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty, llvm_ptrptr_ty], [], + "llvm.va_copy">; + def int_vaend : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty], [], "llvm.va_end">; + + //===------------------- Garbage Collection Intrinsics --------------------===// + // + def int_gcroot : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty, llvm_ptr_ty]>; + def int_gcread : Intrinsic<[llvm_ptr_ty, llvm_ptrptr_ty], [InstrReadArgMem]>; + def int_gcwrite : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptrptr_ty], + [InstrWriteArgMem]>; + + //===--------------------- Code Generator Intrinsics ----------------------===// + // + def int_returnaddress : Intrinsic<[llvm_ptr_ty, llvm_uint_ty], [InstrNoMem]>; + def int_frameaddress : Intrinsic<[llvm_ptr_ty, llvm_uint_ty], [InstrNoMem]>; + def int_stacksave : Intrinsic<[llvm_ptr_ty]>; + def int_stackrestore : Intrinsic<[llvm_ptr_ty]>; + def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty, + llvm_uint_ty, llvm_uint_ty]>; + def int_pcmarker : Intrinsic<[llvm_void_ty, llvm_uint_ty]>; + + def int_readcyclecounter : Intrinsic<[llvm_ulong_ty]>; + + //===------------------- Standard C Library Intrinsics --------------------===// + // + + let Properties = [InstrWriteArgMem] in { + def int_memcpy_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty, + llvm_uint_ty, llvm_uint_ty]>; + def int_memcpy_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty, + llvm_ulong_ty, llvm_uint_ty]>; + def int_memmove_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty, + llvm_uint_ty, llvm_uint_ty]>; + def int_memmove_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty, + llvm_ulong_ty, llvm_uint_ty]>; + def int_memset_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ubyte_ty, + llvm_uint_ty, llvm_uint_ty]>; + def int_memset_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ubyte_ty, + llvm_ulong_ty, llvm_uint_ty]>; + } + + let Properties = [InstrNoMem] in { + def int_isunordered_f32 : Intrinsic<[llvm_float_ty, llvm_float_ty]>; + def int_isunordered_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>; + def int_sqrt_f32 : Intrinsic<[llvm_float_ty , llvm_float_ty]>; + def int_sqrt_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>; + } + + // NOTE: these are internal interfaces. + def int_setjmp : Intrinsic<[llvm_int_ty , llvm_ptr_ty]>; + def int_longjmp : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_int_ty]>; + def int_sigsetjmp : Intrinsic<[llvm_int_ty , llvm_ptr_ty]>; + def int_siglongjmp : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_int_ty]>; + + //===-------------------- Bit Manipulation Intrinsics ---------------------===// + // + + // None of these intrinsics accesses memory at all. + let Properties = [InstrNoMem] in { + def int_bswap_i16 : Intrinsic<[llvm_ushort_ty, llvm_ushort_ty]>; + def int_bswap_i32 : Intrinsic<[llvm_uint_ty, llvm_uint_ty]>; + def int_bswap_i64 : Intrinsic<[llvm_ulong_ty, llvm_ulong_ty]>; + + def int_ctpop_i8 : Intrinsic<[llvm_ubyte_ty, llvm_ubyte_ty]>; + def int_ctpop_i16 : Intrinsic<[llvm_ushort_ty, llvm_ushort_ty]>; + def int_ctpop_i32 : Intrinsic<[llvm_uint_ty, llvm_uint_ty]>; + def int_ctpop_i64 : Intrinsic<[llvm_ulong_ty, llvm_ulong_ty]>; + + def int_ctlz_i8 : Intrinsic<[llvm_ubyte_ty, llvm_ubyte_ty]>; + def int_ctlz_i16 : Intrinsic<[llvm_ushort_ty, llvm_ushort_ty]>; + def int_ctlz_i32 : Intrinsic<[llvm_uint_ty, llvm_uint_ty]>; + def int_ctlz_i64 : Intrinsic<[llvm_ulong_ty, llvm_ulong_ty]>; + + def int_cttz_i8 : Intrinsic<[llvm_ubyte_ty, llvm_ubyte_ty]>; + def int_cttz_i16 : Intrinsic<[llvm_ushort_ty, llvm_ushort_ty]>; + def int_cttz_i32 : Intrinsic<[llvm_uint_ty, llvm_uint_ty]>; + def int_cttz_i64 : Intrinsic<[llvm_ulong_ty, llvm_ulong_ty]>; + } + + //===------------------------ Debugger Intrinsics -------------------------===// + // + + def int_dbg_stoppoint : Intrinsic<[llvm_anchor_ty, llvm_uint_ty, + llvm_uint_ty, llvm_descriptor_ty]>; + def int_dbg_region_start : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; + def int_dbg_region_end : Intrinsic<[llvm_anchor_ty, llvm_anchor_ty]>; + def int_dbg_func_start : Intrinsic<[llvm_anchor_ty, llvm_descriptor_ty]>; + // dbg_declare, // Declare a local object + From lattner at cs.uiuc.edu Thu Mar 2 20:34:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Mar 2006 20:34:39 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200603030234.UAA04384@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.45 -> 1.46 --- Log message: remove a bunch of long-dead testing code --- Diffs of the changes: (+1 -331) TableGen.cpp | 332 ----------------------------------------------------------- 1 files changed, 1 insertion(+), 331 deletions(-) Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.45 llvm/utils/TableGen/TableGen.cpp:1.46 --- llvm/utils/TableGen/TableGen.cpp:1.45 Thu Mar 2 20:32:46 2006 +++ llvm/utils/TableGen/TableGen.cpp Thu Mar 2 20:34:28 2006 @@ -40,8 +40,7 @@ GenDAGISel, GenSubtarget, GenIntrinsic, - PrintEnums, - Parse + PrintEnums }; namespace { @@ -71,8 +70,6 @@ "Generate intrinsic information"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), - clEnumValN(Parse, "parse", - "Interpret machine code (testing only)"), clEnumValEnd)); cl::opt @@ -98,330 +95,6 @@ RecordKeeper llvm::Records; -static Init *getBit(Record *R, unsigned BitNo) { - const std::vector &V = R->getValues(); - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (V[i].getPrefix()) { - assert(dynamic_cast(V[i].getValue()) && - "Can only handle fields of bits<> type!"); - BitsInit *I = (BitsInit*)V[i].getValue(); - if (BitNo < I->getNumBits()) - return I->getBit(BitNo); - BitNo -= I->getNumBits(); - } - - std::cerr << "Cannot find requested bit!\n"; - exit(1); - return 0; -} - -static unsigned getNumBits(Record *R) { - const std::vector &V = R->getValues(); - unsigned Num = 0; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (V[i].getPrefix()) { - assert(dynamic_cast(V[i].getValue()) && - "Can only handle fields of bits<> type!"); - Num += ((BitsInit*)V[i].getValue())->getNumBits(); - } - return Num; -} - -static bool BitsAreFixed(Record *I1, Record *I2, unsigned BitNo) { - return dynamic_cast(getBit(I1, BitNo)) && - dynamic_cast(getBit(I2, BitNo)); -} - -static bool BitsAreEqual(Record *I1, Record *I2, unsigned BitNo) { - BitInit *Bit1 = dynamic_cast(getBit(I1, BitNo)); - BitInit *Bit2 = dynamic_cast(getBit(I2, BitNo)); - - return Bit1 && Bit2 && Bit1->getValue() == Bit2->getValue(); -} - -static bool BitRangesEqual(Record *I1, Record *I2, - unsigned Start, unsigned End) { - for (unsigned i = Start; i != End; ++i) - if (!BitsAreEqual(I1, I2, i)) - return false; - return true; -} - -static unsigned getFirstFixedBit(Record *R, unsigned FirstFixedBit) { - // Look for the first bit of the pair that are required to be 0 or 1. - while (!dynamic_cast(getBit(R, FirstFixedBit))) - ++FirstFixedBit; - return FirstFixedBit; -} - -static void FindInstDifferences(Record *I1, Record *I2, - unsigned FirstFixedBit, unsigned MaxBits, - unsigned &FirstVaryingBitOverall, - unsigned &LastFixedBitOverall) { - // Compare the first instruction to the rest of the instructions, looking for - // fields that differ. - // - unsigned FirstVaryingBit = FirstFixedBit; - while (FirstVaryingBit < MaxBits && BitsAreEqual(I1, I2, FirstVaryingBit)) - ++FirstVaryingBit; - - unsigned LastFixedBit = FirstVaryingBit; - while (LastFixedBit < MaxBits && BitsAreFixed(I1, I2, LastFixedBit)) - ++LastFixedBit; - - if (FirstVaryingBit < FirstVaryingBitOverall) - FirstVaryingBitOverall = FirstVaryingBit; - if (LastFixedBit < LastFixedBitOverall) - LastFixedBitOverall = LastFixedBit; -} - -static bool getBitValue(Record *R, unsigned BitNo) { - Init *I = getBit(R, BitNo); - assert(dynamic_cast(I) && "Bit should be fixed!"); - return ((BitInit*)I)->getValue(); -} - -struct BitComparator { - unsigned BitBegin, BitEnd; - BitComparator(unsigned B, unsigned E) : BitBegin(B), BitEnd(E) {} - - bool operator()(Record *R1, Record *R2) { // Return true if R1 is less than R2 - for (unsigned i = BitBegin; i != BitEnd; ++i) { - bool V1 = getBitValue(R1, i), V2 = getBitValue(R2, i); - if (V1 < V2) - return true; - else if (V2 < V1) - return false; - } - return false; - } -}; - -static void PrintRange(std::vector::iterator I, - std::vector::iterator E) { - while (I != E) std::cerr << **I++; -} - -static bool getMemoryBit(unsigned char *M, unsigned i) { - return (M[i/8] & (1 << (i&7))) != 0; -} - -static unsigned getFirstFixedBitInSequence(std::vector::iterator IB, - std::vector::iterator IE, - unsigned StartBit) { - unsigned FirstFixedBit = 0; - for (std::vector::iterator I = IB; I != IE; ++I) - FirstFixedBit = std::max(FirstFixedBit, getFirstFixedBit(*I, StartBit)); - return FirstFixedBit; -} - -// ParseMachineCode - Try to split the vector of instructions (which is -// intentionally taken by-copy) in half, narrowing down the possible -// instructions that we may have found. Eventually, this list will get pared -// down to zero or one instruction, in which case we have a match or failure. -// -static Record *ParseMachineCode(std::vector::iterator InstsB, - std::vector::iterator InstsE, - unsigned char *M) { - assert(InstsB != InstsE && "Empty range?"); - if (InstsB+1 == InstsE) { - // Only a single instruction, see if we match it... - Record *Inst = *InstsB; - for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i) - if (BitInit *BI = dynamic_cast(getBit(Inst, i))) - if (getMemoryBit(M, i) != BI->getValue()) - throw std::string("Parse failed!\n"); - return Inst; - } - - unsigned MaxBits = ~0; - for (std::vector::iterator I = InstsB; I != InstsE; ++I) - MaxBits = std::min(MaxBits, getNumBits(*I)); - - unsigned FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, 0); - unsigned FirstVaryingBit, LastFixedBit; - do { - FirstVaryingBit = ~0; - LastFixedBit = ~0; - for (std::vector::iterator I = InstsB+1; I != InstsE; ++I) - FindInstDifferences(*InstsB, *I, FirstFixedBit, MaxBits, - FirstVaryingBit, LastFixedBit); - if (FirstVaryingBit == MaxBits) { - std::cerr << "ERROR: Could not find bit to distinguish between " - << "the following entries!\n"; - PrintRange(InstsB, InstsE); - } - -#if 0 - std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit - << ": " << InstsE-InstsB << "\n"; -#endif - - FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, FirstVaryingBit); - } while (FirstVaryingBit != FirstFixedBit); - - //std::cerr << "\n\nXXXXXXXXXXXXXXXXX\n\n"; - //PrintRange(InstsB, InstsE); - - // Sort the Insts list so that the entries have all of the bits in the range - // [FirstVaryingBit,LastFixedBit) sorted. These bits are all guaranteed to be - // set to either 0 or 1 (BitInit values), which simplifies things. - // - std::sort(InstsB, InstsE, BitComparator(FirstVaryingBit, LastFixedBit)); - - // Once the list is sorted by these bits, split the bit list into smaller - // lists, and recurse on each one. - // - std::vector::iterator RangeBegin = InstsB; - Record *Match = 0; - while (RangeBegin != InstsE) { - std::vector::iterator RangeEnd = RangeBegin+1; - while (RangeEnd != InstsE && - BitRangesEqual(*RangeBegin, *RangeEnd, FirstVaryingBit, LastFixedBit)) - ++RangeEnd; - - // We just identified a range of equal instructions. If this range is the - // input range, we were not able to distinguish between the instructions in - // the set. Print an error and exit! - // - if (RangeBegin == InstsB && RangeEnd == InstsE) { - std::cerr << "Error: Could not distinguish among the following insts!:\n"; - PrintRange(InstsB, InstsE); - exit(1); - } - -#if 0 - std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit - << ": [" << RangeEnd-RangeBegin << "] - "; - for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i) - std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " "; - std::cerr << "\n"; -#endif - - if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) { - if (Match) { - std::cerr << "Error: Multiple matches found:\n"; - PrintRange(InstsB, InstsE); - } - - assert(Match == 0 && "Multiple matches??"); - Match = R; - } - RangeBegin = RangeEnd; - } - - return Match; -} - -static void PrintValue(Record *I, unsigned char *Ptr, const RecordVal &Val) { - assert(dynamic_cast(Val.getValue()) && - "Can only handle undefined bits<> types!"); - BitsInit *BI = (BitsInit*)Val.getValue(); - assert(BI->getNumBits() <= 32 && "Can only handle fields up to 32 bits!"); - - unsigned Value = 0; - const std::vector &Vals = I->getValues(); - - // Start by filling in fixed values... - for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) - if (BitInit *B = dynamic_cast(BI->getBit(i))) - Value |= B->getValue() << i; - - // Loop over all of the fields in the instruction adding in any - // contributions to this value (due to bit references). - // - unsigned Offset = 0; - for (unsigned f = 0, e = Vals.size(); f != e; ++f) - if (Vals[f].getPrefix()) { - BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue(); - if (&Vals[f] == &Val) { - // Read the bits directly now... - for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) - Value |= getMemoryBit(Ptr, Offset+i) << i; - break; - } - - // Scan through the field looking for bit initializers of the current - // variable... - for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i) - if (VarBitInit *VBI = - dynamic_cast(FieldInitializer->getBit(i))) { - TypedInit *TI = VBI->getVariable(); - if (VarInit *VI = dynamic_cast(TI)) { - if (VI->getName() == Val.getName()) - Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum(); - } else if (FieldInit *FI = dynamic_cast(TI)) { - // FIXME: implement this! - std::cerr << "FIELD INIT not implemented yet!\n"; - } - } - Offset += FieldInitializer->getNumBits(); - } - - std::cout << "0x" << std::hex << Value << std::dec; -} - -static void PrintInstruction(Record *I, unsigned char *Ptr) { - std::cout << "Inst " << getNumBits(I)/8 << " bytes: " - << "\t" << I->getName() << "\t" << *I->getValue("Name")->getValue() - << "\t"; - - const std::vector &Vals = I->getValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) - if (!Vals[i].getValue()->isComplete()) { - std::cout << Vals[i].getName() << "="; - PrintValue(I, Ptr, Vals[i]); - std::cout << "\t"; - } - - std::cout << "\n";// << *I; -} - -static void ParseMachineCode() { - // X86 code - unsigned char Buffer[] = { - 0x55, // push EBP - 0x89, 0xE5, // mov EBP, ESP - //0x83, 0xEC, 0x08, // sub ESP, 0x8 - 0xE8, 1, 2, 3, 4, // call +0x04030201 - 0x89, 0xEC, // mov ESP, EBP - 0x5D, // pop EBP - 0xC3, // ret - 0x90, // nop - 0xC9, // leave - 0x89, 0xF6, // mov ESI, ESI - 0x68, 1, 2, 3, 4, // push 0x04030201 - 0x5e, // pop ESI - 0xFF, 0xD0, // call EAX - 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201 - 0x85, 0xC0, // test EAX, EAX - 0xF4, // hlt - }; - -#if 0 - // SparcV9 code - unsigned char Buffer[] = { 0xbf, 0xe0, 0x20, 0x1f, 0x1, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, 0x1, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xaf, 0xe8, 0x20, 0x17 - }; -#endif - - std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); - - unsigned char *BuffPtr = Buffer; - while (1) { - Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr); - PrintInstruction(R, BuffPtr); - - unsigned Bits = getNumBits(R); - assert((Bits & 7) == 0 && "Instruction is not an even number of bytes!"); - BuffPtr += Bits/8; - } -} - int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); ParseFile(InputFilename, IncludeDirs); @@ -444,9 +117,6 @@ case PrintRecords: *Out << Records; // No argument, dump all contents break; - case Parse: - ParseMachineCode(); - break; case GenEmitter: CodeEmitterGen(Records).run(*Out); break; From jeffc at jolt-lang.org Thu Mar 2 21:25:19 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 2 Mar 2006 21:25:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603030325.VAA04659@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.7 -> 1.8 --- Log message: Fix VC++ compilation errors. --- Diffs of the changes: (+4 -4) ScheduleDAGList.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.7 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.8 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.7 Thu Mar 2 15:38:29 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Thu Mar 2 21:25:07 2006 @@ -80,7 +80,7 @@ if (Preds.size() != 0) { std::cerr << "Predecessors :\n"; - for (std::set::iterator I = Preds.begin(), + for (std::set::const_iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) { std::cerr << " "; (*I)->dump(G, false); @@ -88,7 +88,7 @@ } if (ChainPreds.size() != 0) { std::cerr << "Chained Preds :\n"; - for (std::set::iterator I = ChainPreds.begin(), + for (std::set::const_iterator I = ChainPreds.begin(), E = ChainPreds.end(); I != E; ++I) { std::cerr << " "; (*I)->dump(G, false); @@ -96,7 +96,7 @@ } if (Succs.size() != 0) { std::cerr << "Successors :\n"; - for (std::set::iterator I = Succs.begin(), + for (std::set::const_iterator I = Succs.begin(), E = Succs.end(); I != E; ++I) { std::cerr << " "; (*I)->dump(G, false); @@ -104,7 +104,7 @@ } if (ChainSuccs.size() != 0) { std::cerr << "Chained succs :\n"; - for (std::set::iterator I = ChainSuccs.begin(), + for (std::set::const_iterator I = ChainSuccs.begin(), E = ChainSuccs.end(); I != E; ++I) { std::cerr << " "; (*I)->dump(G, false); From lattner at cs.uiuc.edu Fri Mar 3 00:14:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 00:14:33 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenIntrinsics.h Message-ID: <200603030614.AAA06008@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenIntrinsics.h updated: 1.1 -> 1.2 --- Log message: Fix pasteo --- Diffs of the changes: (+1 -1) CodeGenIntrinsics.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/CodeGenIntrinsics.h diff -u llvm/utils/TableGen/CodeGenIntrinsics.h:1.1 llvm/utils/TableGen/CodeGenIntrinsics.h:1.2 --- llvm/utils/TableGen/CodeGenIntrinsics.h:1.1 Thu Mar 2 20:32:46 2006 +++ llvm/utils/TableGen/CodeGenIntrinsics.h Fri Mar 3 00:13:41 2006 @@ -2,7 +2,7 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under +// This file was developed by Chris Lattner and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// From evan.cheng at apple.com Fri Mar 3 00:23:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:23:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200603030623.AAA06061@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.8 -> 1.9 --- Log message: A bit more tweaking --- Diffs of the changes: (+24 -6) ScheduleDAGList.cpp | 30 ++++++++++++++++++++++++------ 1 files changed, 24 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.8 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.9 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.8 Thu Mar 2 21:25:07 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Fri Mar 3 00:23:43 2006 @@ -43,6 +43,7 @@ int NumChainSuccsLeft; // # of chain succs not scheduled. int Priority1; // Scheduling priority 1. int Priority2; // Scheduling priority 2. + bool isTwoAddress; // Is a two-address instruction. bool isDefNUseOperand; // Is a def&use operand. unsigned Latency; // Node latency. unsigned CycleBound; // Upper/lower cycle to be scheduled at. @@ -52,7 +53,8 @@ SUnit(SDNode *node) : Node(node), NumPredsLeft(0), NumSuccsLeft(0), NumChainPredsLeft(0), NumChainSuccsLeft(0), - Priority1(INT_MIN), Priority2(INT_MIN), isDefNUseOperand(false), + Priority1(INT_MIN), Priority2(INT_MIN), + isTwoAddress(false), isDefNUseOperand(false), Latency(0), CycleBound(0), Slot(0), Next(NULL) {} void dump(const SelectionDAG *G, bool All=true) const; @@ -120,6 +122,20 @@ bool RFloater = (right->Preds.size() == 0); int LBonus = (int)left ->isDefNUseOperand; int RBonus = (int)right->isDefNUseOperand; + + // Special tie breaker: if two nodes share a operand, the one that + // use it as a def&use operand is preferred. + if (left->isTwoAddress && !right->isTwoAddress) { + SDNode *DUNode = left->Node->getOperand(0).Val; + if (DUNode->isOperand(right->Node)) + LBonus++; + } + if (!left->isTwoAddress && right->isTwoAddress) { + SDNode *DUNode = right->Node->getOperand(0).Val; + if (DUNode->isOperand(left->Node)) + RBonus++; + } + int LPriority1 = left ->Priority1 - LBonus; int RPriority1 = right->Priority1 - RBonus; int LPriority2 = left ->Priority2 + LBonus; @@ -138,8 +154,6 @@ else if (LPriority1 == RPriority1) if (left->CycleBound > right->CycleBound) return true; - else - return left->Node->getNodeDepth() < right->Node->getNodeDepth(); return false; } @@ -238,6 +252,9 @@ /// its predecessors. If a predecessor pending count is zero, add it to the /// Available queue. void ScheduleDAGList::ScheduleNode(SUnit *SU) { + DEBUG(std::cerr << "*** Scheduling: "); + DEBUG(SU->dump(&DAG, false)); + Sequence.push_back(SU); SU->Slot = CurrCycle; @@ -283,8 +300,6 @@ for (unsigned i = 0, e = NotReady.size(); i != e; ++i) Available.push(NotReady[i]); - DEBUG(std::cerr << "*** Scheduling: "); - DEBUG(CurrNode->dump(&DAG, false)); ScheduleNode(CurrNode); } @@ -402,6 +417,9 @@ for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { SDNode *N = SU->Node; NodeInfo *NI = getNI(N); + + if (N->isTargetOpcode() && TII->isTwoAddrInstr(N->getTargetOpcode())) + SU->isTwoAddress = true; if (NI->isInGroup()) { // Find all predecessors (of the group). @@ -446,7 +464,7 @@ SU->NumPredsLeft++; if (OpSU->Succs.insert(SU).second) OpSU->NumSuccsLeft++; - if (j == 0 && TII->isTwoAddrInstr(N->getTargetOpcode())) + if (j == 0 && SU->isTwoAddress) OpSU->isDefNUseOperand = true; } } From evan.cheng at apple.com Fri Mar 3 00:25:07 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:25:07 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200603030625.AAA06084@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.106 -> 1.107 --- Log message: Added isOperand(N): true if this is an operand of N --- Diffs of the changes: (+7 -0) SelectionDAGNodes.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.106 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.107 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.106 Thu Mar 2 18:18:00 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Mar 3 00:24:54 2006 @@ -542,6 +542,7 @@ inline const SDOperand &getOperand(unsigned i) const; inline bool isTargetOpcode() const; inline unsigned getTargetOpcode() const; + inline const bool isOperand(SDNode *N) const; /// hasOneUse - Return true if there is exactly one operation using this /// result value of the defining operator. @@ -631,6 +632,9 @@ // isOnlyUse - Return true if this node is the only use of N. bool isOnlyUse(SDNode *N) const; + // isOperand - Return true if this node is an operand of N. + bool isOperand(SDNode *N) const; + /// getNumOperands - Return the number of values used by this operation. /// unsigned getNumOperands() const { return NumOperands; } @@ -937,6 +941,9 @@ inline unsigned SDOperand::getTargetOpcode() const { return Val->getTargetOpcode(); } +inline const bool SDOperand::isOperand(SDNode *N) const { + return Val->isOperand(N); +} inline bool SDOperand::hasOneUse() const { return Val->hasNUsesOfValue(1, ResNo); } From evan.cheng at apple.com Fri Mar 3 00:25:07 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:25:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200603030625.AAA06088@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.263 -> 1.264 --- Log message: Added isOperand(N): true if this is an operand of N --- Diffs of the changes: (+7 -0) SelectionDAG.cpp | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.263 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.264 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.263 Thu Mar 2 18:19:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Mar 3 00:24:54 2006 @@ -2533,6 +2533,13 @@ return Seen; } +// isOperand - Return true if this node is an operand of N. +bool SDNode::isOperand(SDNode *N) const { + for (unsigned i = 0, e = N->NumOperands; i != e; ++i) + if (this == N->OperandList[i].Val) + return true; + return false; +} const char *SDNode::getOperationName(const SelectionDAG *G) const { switch (getOpcode()) { From evan.cheng at apple.com Fri Mar 3 00:42:45 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:42:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200603030642.AAA06210@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.264 -> 1.265 --- Log message: SDOperand::isOperand should not be a forwarding. It must check *this against N's operands. --- Diffs of the changes: (+7 -0) SelectionDAG.cpp | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.264 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.265 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.264 Fri Mar 3 00:24:54 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Mar 3 00:42:32 2006 @@ -2534,6 +2534,13 @@ } // isOperand - Return true if this node is an operand of N. +bool SDOperand::isOperand(SDNode *N) const { + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + if (*this == N->getOperand(i)) + return true; + return false; +} + bool SDNode::isOperand(SDNode *N) const { for (unsigned i = 0, e = N->NumOperands; i != e; ++i) if (this == N->OperandList[i].Val) From evan.cheng at apple.com Fri Mar 3 00:42:45 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:42:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200603030642.AAA06214@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.107 -> 1.108 --- Log message: SDOperand::isOperand should not be a forwarding. It must check *this against N's operands. --- Diffs of the changes: (+3 -4) SelectionDAGNodes.h | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.107 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.108 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.107 Fri Mar 3 00:24:54 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Mar 3 00:42:32 2006 @@ -531,6 +531,9 @@ return SDOperand(Val, R); } + // isOperand - Return true if this node is an operand of N. + bool isOperand(SDNode *N) const; + /// getValueType - Return the ValueType of the referenced return value. /// inline MVT::ValueType getValueType() const; @@ -542,7 +545,6 @@ inline const SDOperand &getOperand(unsigned i) const; inline bool isTargetOpcode() const; inline unsigned getTargetOpcode() const; - inline const bool isOperand(SDNode *N) const; /// hasOneUse - Return true if there is exactly one operation using this /// result value of the defining operator. @@ -941,9 +943,6 @@ inline unsigned SDOperand::getTargetOpcode() const { return Val->getTargetOpcode(); } -inline const bool SDOperand::isOperand(SDNode *N) const { - return Val->isOperand(N); -} inline bool SDOperand::hasOneUse() const { return Val->hasNUsesOfValue(1, ResNo); } From evan.cheng at apple.com Fri Mar 3 00:59:12 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:59:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200603030659.AAA06387@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.42 -> 1.43 --- Log message: Number of NodeTypes now exceeds 128. --- Diffs of the changes: (+1 -1) TargetLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.42 llvm/lib/Target/TargetLowering.cpp:1.43 --- llvm/lib/Target/TargetLowering.cpp:1.42 Tue Feb 28 22:52:55 2006 +++ llvm/lib/Target/TargetLowering.cpp Fri Mar 3 00:58:59 2006 @@ -21,7 +21,7 @@ TargetLowering::TargetLowering(TargetMachine &tm) : TM(tm), TD(TM.getTargetData()) { - assert(ISD::BUILTIN_OP_END <= 128 && + assert(ISD::BUILTIN_OP_END <= 156 && "Fixed size array in TargetLowering is not large enough!"); // All operations default to being supported. memset(OpActions, 0, sizeof(OpActions)); From evan.cheng at apple.com Fri Mar 3 00:59:12 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 00:59:12 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200603030659.AAA06391@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.57 -> 1.58 --- Log message: Number of NodeTypes now exceeds 128. --- Diffs of the changes: (+2 -2) TargetLowering.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.57 llvm/include/llvm/Target/TargetLowering.h:1.58 --- llvm/include/llvm/Target/TargetLowering.h:1.57 Tue Feb 28 22:52:29 2006 +++ llvm/include/llvm/Target/TargetLowering.h Fri Mar 3 00:58:59 2006 @@ -642,7 +642,7 @@ /// Most operations are Legal (aka, supported natively by the target), but /// operations that are not should be described. Note that operations on /// non-legal value types are not described here. - uint64_t OpActions[128]; + uint64_t OpActions[156]; ValueTypeActionImpl ValueTypeActions; @@ -654,7 +654,7 @@ /// TargetDAGCombineArray - Targets can specify ISD nodes that they would /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(), /// which sets a bit in this array. - unsigned char TargetDAGCombineArray[128/(sizeof(unsigned char)*8)]; + unsigned char TargetDAGCombineArray[156/(sizeof(unsigned char)*8)]; protected: /// When lowering %llvm.memset this field specifies the maximum number of From evan.cheng at apple.com Fri Mar 3 01:01:19 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 01:01:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200603030701.BAA06456@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.309 -> 1.310 SelectionDAGISel.cpp updated: 1.177 -> 1.178 --- Log message: Add more vector NodeTypes: VSDIV, VUDIV, VAND, VOR, and VXOR. --- Diffs of the changes: (+20 -8) LegalizeDAG.cpp | 18 ++++++++++++++---- SelectionDAGISel.cpp | 10 ++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.309 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.310 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.309 Thu Mar 2 18:19:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Mar 3 01:01:07 2006 @@ -152,9 +152,14 @@ static unsigned getScalarizedOpcode(unsigned VecOp, MVT::ValueType VT) { switch (VecOp) { default: assert(0 && "Don't know how to scalarize this opcode!"); - case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD; - case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB; - case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL; + case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD; + case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB; + case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL; + case ISD::VSDIV: return MVT::isInteger(VT) ? ISD::SDIV: ISD::FDIV; + case ISD::VUDIV: return MVT::isInteger(VT) ? ISD::UDIV: ISD::FDIV; + case ISD::VAND: return MVT::isInteger(VT) ? ISD::AND : 0; + case ISD::VOR: return MVT::isInteger(VT) ? ISD::OR : 0; + case ISD::VXOR: return MVT::isInteger(VT) ? ISD::XOR : 0; } } @@ -3646,7 +3651,12 @@ } case ISD::VADD: case ISD::VSUB: - case ISD::VMUL: { + case ISD::VMUL: + case ISD::VSDIV: + case ISD::VUDIV: + case ISD::VAND: + case ISD::VOR: + case ISD::VXOR: { unsigned NumElements =cast(Node->getOperand(0))->getValue(); MVT::ValueType EVT = cast(Node->getOperand(1))->getVT(); MVT::ValueType TVT = (NumElements/2 > 1) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.177 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.178 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.177 Thu Mar 2 18:19:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 3 01:01:07 2006 @@ -496,15 +496,17 @@ } void visitDiv(User &I) { const Type *Ty = I.getType(); - visitBinary(I, Ty->isSigned() ? ISD::SDIV : ISD::UDIV, ISD::FDIV, 0); + visitBinary(I, + Ty->isSigned() ? ISD::SDIV : ISD::UDIV, ISD::FDIV, + Ty->isSigned() ? ISD::VSDIV : ISD::VUDIV); } void visitRem(User &I) { const Type *Ty = I.getType(); visitBinary(I, Ty->isSigned() ? ISD::SREM : ISD::UREM, ISD::FREM, 0); } - void visitAnd(User &I) { visitBinary(I, ISD::AND, 0, 0); } - void visitOr (User &I) { visitBinary(I, ISD::OR, 0, 0); } - void visitXor(User &I) { visitBinary(I, ISD::XOR, 0, 0); } + void visitAnd(User &I) { visitBinary(I, ISD::AND, 0, ISD::VAND); } + void visitOr (User &I) { visitBinary(I, ISD::OR, 0, ISD::VOR); } + void visitXor(User &I) { visitBinary(I, ISD::XOR, 0, ISD::VXOR); } void visitShl(User &I) { visitShift(I, ISD::SHL); } void visitShr(User &I) { visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA); From evan.cheng at apple.com Fri Mar 3 01:01:20 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 01:01:20 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200603030701.BAA06460@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.108 -> 1.109 --- Log message: Add more vector NodeTypes: VSDIV, VUDIV, VAND, VOR, and VXOR. --- Diffs of the changes: (+2 -1) SelectionDAGNodes.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.108 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.109 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.108 Fri Mar 3 00:42:32 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Mar 3 01:01:07 2006 @@ -147,7 +147,8 @@ // the elements. The order is count, type, op0, op1. All vector opcodes, // including VLOAD and VConstant must currently have count and type as // their 1st and 2nd arguments. - VADD, VSUB, VMUL, + VADD, VSUB, VMUL, VSDIV, VUDIV, + VAND, VOR, VXOR, // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing // an unsigned/signed value of type i[2*n], then return the top part. From jlaskey at apple.com Fri Mar 3 09:07:19 2006 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 3 Mar 2006 09:07:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200603031507.JAA19222@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.40 -> 1.41 MachineDebugInfo.cpp updated: 1.22 -> 1.23 --- Log message: Adding basic structure support. --- Diffs of the changes: (+46 -4) DwarfWriter.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- MachineDebugInfo.cpp | 7 ++++++- 2 files changed, 46 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.40 llvm/lib/CodeGen/DwarfWriter.cpp:1.41 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.40 Wed Mar 1 17:52:37 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Fri Mar 3 09:06:57 2006 @@ -41,6 +41,8 @@ class DIE; //===----------------------------------------------------------------------===// +// CompileUnit - This dwarf writer support class manages information associate +// with a source file. class CompileUnit { private: CompileUnitDesc *Desc; // Compile unit debug descriptor. @@ -505,6 +507,13 @@ case DW_FORM_data8: DW.EmitInt64(Integer); break; case DW_FORM_udata: DW.EmitULEB128Bytes(Integer); break; case DW_FORM_sdata: DW.EmitSLEB128Bytes(Integer); break; + // FIXME - Punting on field offsets. + case DW_FORM_block1: { + DW.EmitInt8(1 + DW.SizeULEB128(Integer)); DW.EOL("Form1 Size"); + DW.EmitInt8(DW_OP_plus_uconst); DW.EOL("DW_OP_plus_uconst"); + DW.EmitULEB128Bytes(Integer); + break; + } default: assert(0 && "DIE Value form not supported yet"); break; } } @@ -520,6 +529,8 @@ case DW_FORM_data8: return sizeof(int64_t); case DW_FORM_udata: return DW.SizeULEB128(Integer); case DW_FORM_sdata: return DW.SizeSLEB128(Integer); + // FIXME - Punting on field offsets. + case DW_FORM_block1: return 2 + DW.SizeULEB128(Integer); default: assert(0 && "DIE Value form not supported yet"); break; } return 0; @@ -1117,10 +1128,36 @@ break; } - case DW_TAG_structure_type: { - break; - } + case DW_TAG_structure_type: case DW_TAG_union_type: { + // FIXME - this is just the basics. + // Add elements to structure type. + for(unsigned i = 0, N = Elements.size(); i < N; ++i) { + DerivedTypeDesc *MemberDesc = cast(Elements[i]); + const std::string &Name = MemberDesc->getName(); + unsigned Line = MemberDesc->getLine(); + TypeDesc *MemTy = MemberDesc->getFromType(); + uint64_t Size = MemberDesc->getSize(); + uint64_t Offset = MemberDesc->getOffset(); + + DIE *Member = new DIE(DW_TAG_member); + if (!Name.empty()) Member->AddString(DW_AT_name, DW_FORM_string, Name); + if (CompileUnitDesc *File = MemberDesc->getFile()) { + CompileUnit *FileUnit = FindCompileUnit(File); + unsigned FileID = FileUnit->getID(); + int Line = TyDesc->getLine(); + Member->AddUInt(DW_AT_decl_file, 0, FileID); + Member->AddUInt(DW_AT_decl_line, 0, Line); + } + if (TypeDesc *FromTy = MemberDesc->getFromType()) { + Member->AddDIEntry(DW_AT_type, DW_FORM_ref4, + NewType(Context, FromTy)); + } + // FIXME - Punt on the Address. + Member->AddUInt(DW_AT_data_member_location, DW_FORM_block1, + Offset >> 3); + Ty->AddChild(Member); + } break; } case DW_TAG_enumeration_type: { Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.22 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.23 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.22 Wed Mar 1 17:52:37 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Fri Mar 3 09:06:57 2006 @@ -516,6 +516,7 @@ case DW_TAG_union_type: case DW_TAG_enumeration_type: return new CompositeTypeDesc(Tag); case DW_TAG_subrange_type: return new SubrangeDesc(); + case DW_TAG_member: return new DerivedTypeDesc(DW_TAG_member); case DW_TAG_enumerator: return new EnumeratorDesc(); default: break; } @@ -673,6 +674,7 @@ , Name("") , File(NULL) , Size(0) +, Offset(0) {} /// ApplyToFields - Target the visitor to the fields of the TypeDesc. @@ -685,6 +687,7 @@ Visitor->Apply((DebugInfoDesc *&)File); Visitor->Apply(Line); Visitor->Apply(Size); + Visitor->Apply(Offset); } /// getDescString - Return a string used to compose global names and labels. @@ -707,7 +710,8 @@ << "Name(\"" << Name << "\"), " << "File(" << File << "), " << "Line(" << Line << "), " - << "Size(" << Size << ")\n"; + << "Size(" << Size << "), " + << "Offset(" << Offset << ")\n"; } #endif @@ -771,6 +775,7 @@ case DW_TAG_const_type: case DW_TAG_volatile_type: case DW_TAG_restrict_type: + case DW_TAG_member: return true; default: break; } From jlaskey at apple.com Fri Mar 3 09:07:18 2006 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 3 Mar 2006 09:07:18 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200603031507.JAA19221@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.26 -> 1.27 --- Log message: Adding basic structure support. --- Diffs of the changes: (+7 -5) MachineDebugInfo.h | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.26 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.27 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.26 Wed Mar 1 17:52:37 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Fri Mar 3 09:06:56 2006 @@ -268,23 +268,25 @@ std::string Name; // Type name (may be empty.) CompileUnitDesc *File; // Declared compile unit (may be NULL.) int Line; // Declared line# (may be zero.) - uint64_t Size; // Type size (may be zero.) + uint64_t Size; // Type bit size (may be zero.) + uint64_t Offset; // Type bit offset (may be zero.) -protected: +public: TypeDesc(unsigned T); -public: // Accessors DebugInfoDesc *getContext() const { return Context; } const std::string &getName() const { return Name; } CompileUnitDesc *getFile() const { return File; } int getLine() const { return Line; } uint64_t getSize() const { return Size; } + uint64_t getOffset() const { return Offset; } void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } void setFile(CompileUnitDesc *U) { File = U; } void setLine(int L) { Line = L; } void setSize(uint64_t S) { Size = S; } + void setOffset(uint64_t O) { Offset = O; } /// ApplyToFields - Target the visitor to the fields of the TypeDesc. /// @@ -413,8 +415,8 @@ /// value ranges. class SubrangeDesc : public DebugInfoDesc { private: - int64_t Lo; // Low value of range - int64_t Hi; // High value of range + int64_t Lo; // Low value of range. + int64_t Hi; // High value of range. public: SubrangeDesc(); From lattner at cs.uiuc.edu Fri Mar 3 10:31:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 10:31:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AutoUpgrade.cpp Message-ID: <200603031631.KAA25110@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AutoUpgrade.cpp updated: 1.9 -> 1.10 --- Log message: Unbreak autouprade of llvm.sqrt, simplify some code. --- Diffs of the changes: (+12 -38) AutoUpgrade.cpp | 50 ++++++++++++-------------------------------------- 1 files changed, 12 insertions(+), 38 deletions(-) Index: llvm/lib/VMCore/AutoUpgrade.cpp diff -u llvm/lib/VMCore/AutoUpgrade.cpp:1.9 llvm/lib/VMCore/AutoUpgrade.cpp:1.10 --- llvm/lib/VMCore/AutoUpgrade.cpp:1.9 Thu Mar 2 17:58:40 2006 +++ llvm/lib/VMCore/AutoUpgrade.cpp Fri Mar 3 10:31:22 2006 @@ -19,45 +19,36 @@ #include "llvm/Intrinsics.h" #include "llvm/SymbolTable.h" #include - using namespace llvm; -// Utility function for getting the correct suffix given a type -static inline const char *getTypeSuffix(const Type* Ty) { - switch (Ty->getTypeID()) { - case Type::ULongTyID: return ".i64"; - case Type::UIntTyID: return ".i32"; - case Type::UShortTyID: return ".i16"; - case Type::UByteTyID: return ".i8"; - case Type::FloatTyID: return ".f32"; - case Type::DoubleTyID: return ".f64"; - default: break; - } - return 0; -} - static Function *getUpgradedUnaryFn(Function *F) { - std::string Name = F->getName()+getTypeSuffix(F->getReturnType()); + const std::string &Name = F->getName(); Module *M = F->getParent(); switch (F->getReturnType()->getTypeID()) { default: return 0; case Type::UByteTyID: case Type::SByteTyID: - return M->getOrInsertFunction(Name, + return M->getOrInsertFunction(Name+".i8", Type::UByteTy, Type::UByteTy, NULL); case Type::UShortTyID: case Type::ShortTyID: - return M->getOrInsertFunction(Name, + return M->getOrInsertFunction(Name+".i16", Type::UShortTy, Type::UShortTy, NULL); case Type::UIntTyID: case Type::IntTyID: - return M->getOrInsertFunction(Name, + return M->getOrInsertFunction(Name+".i32", Type::UIntTy, Type::UIntTy, NULL); case Type::ULongTyID: case Type::LongTyID: - return M->getOrInsertFunction(Name, + return M->getOrInsertFunction(Name+".i64", Type::ULongTy, Type::ULongTy, NULL); -} + case Type::FloatTyID: + return M->getOrInsertFunction(Name+".f32", + Type::FloatTy, Type::FloatTy, NULL); + case Type::DoubleTyID: + return M->getOrInsertFunction(Name+".f64", + Type::DoubleTy, Type::DoubleTy, NULL); + } } static Function *getUpgradedIntrinsic(Function *F) { @@ -107,23 +98,6 @@ return 0; } -// This assumes the Function is one of the intrinsics we upgraded. -static inline const Type* getTypeFromFunction(Function *F) { - const Type* Ty = F->getReturnType(); - if (Ty->isFloatingPoint()) - return Ty; - if (Ty->isSigned()) - return Ty->getUnsignedVersion(); - if (Ty->isInteger()) - return Ty; - if (Ty == Type::BoolTy) { - Function::const_arg_iterator ArgIt = F->arg_begin(); - if (ArgIt != F->arg_end()) - return ArgIt->getType(); - } - return 0; -} - // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to // their non-overloaded variants by appending the appropriate suffix based on // the argument types. From evan.cheng at apple.com Fri Mar 3 12:58:22 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 12:58:22 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-03-02-InstrSchedBug.ll Message-ID: <200603031858.MAA26212@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-03-02-InstrSchedBug.ll added (r1.1) --- Log message: Add another test case for instruction scheduling. --- Diffs of the changes: (+10 -0) 2006-03-02-InstrSchedBug.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-03-02-InstrSchedBug.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-03-02-InstrSchedBug.ll:1.1 *** /dev/null Fri Mar 3 12:58:19 2006 --- llvm/test/Regression/CodeGen/X86/2006-03-02-InstrSchedBug.ll Fri Mar 3 12:58:09 2006 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | llc -march=x86 -stats 2>&1 | grep 'asm-printer' | grep 7 + + int %g(int %a, int %b) { + %tmp.1 = shl int %b, ubyte 1 + %tmp.3 = add int %tmp.1, %a + %tmp.5 = mul int %tmp.3, %a + %tmp.8 = mul int %b, %b + %tmp.9 = add int %tmp.5, %tmp.8 + ret int %tmp.9 + } From lattner at cs.uiuc.edu Fri Mar 3 13:34:40 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 13:34:40 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.cpp.cvs FileLexer.l FileLexer.l.cvs Message-ID: <200603031934.NAA26629@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.cpp.cvs updated: 1.3 -> 1.4 FileLexer.l updated: 1.27 -> 1.28 FileLexer.l.cvs updated: 1.2 -> 1.3 --- Log message: Silence a warning. --- Diffs of the changes: (+4 -4) FileLexer.cpp.cvs | 4 ++-- FileLexer.l | 2 +- FileLexer.l.cvs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/FileLexer.cpp.cvs diff -u llvm/utils/TableGen/FileLexer.cpp.cvs:1.3 llvm/utils/TableGen/FileLexer.cpp.cvs:1.4 --- llvm/utils/TableGen/FileLexer.cpp.cvs:1.3 Thu Mar 2 19:47:37 2006 +++ llvm/utils/TableGen/FileLexer.cpp.cvs Fri Mar 3 13:34:28 2006 @@ -21,7 +21,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /var/cvs/llvm/llvm/utils/TableGen/FileLexer.cpp.cvs,v 1.3 2006/03/03 01:47:37 lattner Exp $ + * $Header: /var/cvs/llvm/llvm/utils/TableGen/FileLexer.cpp.cvs,v 1.4 2006/03/03 19:34:28 lattner Exp $ */ #define FLEX_SCANNER @@ -609,7 +609,7 @@ std::string NextFilename; for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) { NextFilename = IncludeDirectories[i] + "/" + Filename; - if (yyin = fopen(NextFilename.c_str(), "r")) + if ((yyin = fopen(NextFilename.c_str(), "r"))) break; } Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.27 llvm/utils/TableGen/FileLexer.l:1.28 --- llvm/utils/TableGen/FileLexer.l:1.27 Thu Mar 2 19:47:14 2006 +++ llvm/utils/TableGen/FileLexer.l Fri Mar 3 13:34:28 2006 @@ -128,7 +128,7 @@ std::string NextFilename; for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) { NextFilename = IncludeDirectories[i] + "/" + Filename; - if (yyin = fopen(NextFilename.c_str(), "r")) + if ((yyin = fopen(NextFilename.c_str(), "r"))) break; } Index: llvm/utils/TableGen/FileLexer.l.cvs diff -u llvm/utils/TableGen/FileLexer.l.cvs:1.2 llvm/utils/TableGen/FileLexer.l.cvs:1.3 --- llvm/utils/TableGen/FileLexer.l.cvs:1.2 Thu Mar 2 19:47:37 2006 +++ llvm/utils/TableGen/FileLexer.l.cvs Fri Mar 3 13:34:28 2006 @@ -128,7 +128,7 @@ std::string NextFilename; for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) { NextFilename = IncludeDirectories[i] + "/" + Filename; - if (yyin = fopen(NextFilename.c_str(), "r")) + if ((yyin = fopen(NextFilename.c_str(), "r"))) break; } From jlaskey at apple.com Fri Mar 3 15:00:26 2006 From: jlaskey at apple.com (Jim Laskey) Date: Fri, 3 Mar 2006 15:00:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200603032100.PAA27915@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.41 -> 1.42 --- Log message: Added support for dwarf block data entries. --- Diffs of the changes: (+248 -49) DwarfWriter.cpp | 297 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 248 insertions(+), 49 deletions(-) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.41 llvm/lib/CodeGen/DwarfWriter.cpp:1.42 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.41 Fri Mar 3 09:06:57 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Fri Mar 3 15:00:14 2006 @@ -174,7 +174,8 @@ isLabel, isAsIsLabel, isDelta, - isEntry + isEntry, + isBlock }; unsigned Type; // Type of the value @@ -208,6 +209,10 @@ static bool classof(const DIEInteger *) { return true; } static bool classof(const DIEValue *I) { return I->Type == isInteger; } + /// BestForm - Choose the best form for integer. + /// + unsigned BestForm(bool IsSigned); + /// EmitValue - Emit integer of appropriate size. /// virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; @@ -316,16 +321,82 @@ static bool classof(const DIEntry *) { return true; } static bool classof(const DIEValue *E) { return E->Type == isEntry; } - /// EmitValue - Emit delta value. + /// EmitValue - Emit die entry offset. /// virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; - /// SizeOf - Determine size of delta value in bytes. + /// SizeOf - Determine size of die entry in bytes. /// virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; }; //===----------------------------------------------------------------------===// +// DIEBlock - A block of values. Primarily used for location expressions. +// +struct DIEBlock : public DIEValue { + unsigned Size; // Size in bytes excluding size header. + std::vector Forms; // Data forms. + std::vector Values; // Block values. + + DIEBlock() + : DIEValue(isBlock) + , Size(0) + , Forms() + , Values() + {} + ~DIEBlock(); + + // Implement isa/cast/dyncast. + static bool classof(const DIEBlock *) { return true; } + static bool classof(const DIEValue *E) { return E->Type == isBlock; } + + /// ComputeSize - calculate the size of the block. + /// + unsigned ComputeSize(DwarfWriter &DW); + + /// BestForm - Choose the best form for data. + /// + unsigned BestForm(); + + /// EmitValue - Emit block data. + /// + virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const; + + /// SizeOf - Determine size of block data in bytes. + /// + virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const; + + /// AddUInt - Add an unsigned integer value. + /// + void AddUInt(unsigned Form, uint64_t Integer); + + /// AddSInt - Add an signed integer value. + /// + void AddSInt(unsigned Form, int64_t Integer); + + /// AddString - Add a std::string value. + /// + void AddString(unsigned Form, const std::string &String); + + /// AddLabel - Add a Dwarf label value. + /// + void AddLabel(unsigned Form, const DWLabel &Label); + + /// AddObjectLabel - Add a non-Dwarf label value. + /// + void AddObjectLabel(unsigned Form, const std::string &Label); + + /// AddDelta - Add a label delta value. + /// + void AddDelta(unsigned Form, const DWLabel &Hi, const DWLabel &Lo); + + /// AddDIEntry - Add a DIE value. + /// + void AddDIEntry(unsigned Form, DIE *Entry); + +}; + +//===----------------------------------------------------------------------===// // DIE - A structured debug information entry. Has an abbreviation which // describes it's organization. class DIE { @@ -381,10 +452,14 @@ void AddDelta(unsigned Attribute, unsigned Form, const DWLabel &Hi, const DWLabel &Lo); - /// AddDIEntry - Add a DIE attribute data and value. + /// AddDIEntry - Add a DIE attribute data and value. /// void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry); + /// AddBlock - Add block data. + /// + void AddBlock(unsigned Attribute, unsigned Form, DIEBlock *Block); + /// Complete - Indicate that all attributes have been added and /// ready to get an abbreviation ID. /// @@ -496,6 +571,21 @@ //===----------------------------------------------------------------------===// +/// BestForm - Choose the best form for integer. +/// +unsigned DIEInteger::BestForm(bool IsSigned) { + if (IsSigned) { + if ((char)Integer == (signed)Integer) return DW_FORM_data1; + if ((short)Integer == (signed)Integer) return DW_FORM_data2; + if ((int)Integer == (signed)Integer) return DW_FORM_data4; + } else { + if ((unsigned char)Integer == Integer) return DW_FORM_data1; + if ((unsigned short)Integer == Integer) return DW_FORM_data2; + if ((unsigned int)Integer == Integer) return DW_FORM_data4; + } + return DW_FORM_data8; +} + /// EmitValue - Emit integer of appropriate size. /// void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const { @@ -507,13 +597,6 @@ case DW_FORM_data8: DW.EmitInt64(Integer); break; case DW_FORM_udata: DW.EmitULEB128Bytes(Integer); break; case DW_FORM_sdata: DW.EmitSLEB128Bytes(Integer); break; - // FIXME - Punting on field offsets. - case DW_FORM_block1: { - DW.EmitInt8(1 + DW.SizeULEB128(Integer)); DW.EOL("Form1 Size"); - DW.EmitInt8(DW_OP_plus_uconst); DW.EOL("DW_OP_plus_uconst"); - DW.EmitULEB128Bytes(Integer); - break; - } default: assert(0 && "DIE Value form not supported yet"); break; } } @@ -529,8 +612,6 @@ case DW_FORM_data8: return sizeof(int64_t); case DW_FORM_udata: return DW.SizeULEB128(Integer); case DW_FORM_sdata: return DW.SizeSLEB128(Integer); - // FIXME - Punting on field offsets. - case DW_FORM_block1: return 2 + DW.SizeULEB128(Integer); default: assert(0 && "DIE Value form not supported yet"); break; } return 0; @@ -569,19 +650,13 @@ /// EmitValue - Emit label value. /// void DIEObjectLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const { - DW.EmitInt8(sizeof(int8_t) + DW.getAddressSize()); - DW.EOL("DW_FORM_block1 length"); - - DW.EmitInt8(DW_OP_addr); - DW.EOL("DW_OP_addr"); - DW.EmitReference(Label); } /// SizeOf - Determine size of label value in bytes. /// unsigned DIEObjectLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const { - return sizeof(int8_t) + sizeof(int8_t) + DW.getAddressSize(); + return DW.getAddressSize(); } //===----------------------------------------------------------------------===// @@ -599,13 +674,13 @@ } //===----------------------------------------------------------------------===// -/// EmitValue - Emit extry offset. +/// EmitValue - Emit die entry offset. /// void DIEntry::EmitValue(const DwarfWriter &DW, unsigned Form) const { DW.EmitInt32(Entry->getOffset()); } -/// SizeOf - Determine size of label value in bytes. +/// SizeOf - Determine size of die value in bytes. /// unsigned DIEntry::SizeOf(const DwarfWriter &DW, unsigned Form) const { return sizeof(int32_t); @@ -613,6 +688,115 @@ //===----------------------------------------------------------------------===// +DIEBlock::~DIEBlock() { + for (unsigned i = 0, N = Values.size(); i < N; ++i) { + delete Values[i]; + } +} + +/// ComputeSize - calculate the size of the block. +/// +unsigned DIEBlock::ComputeSize(DwarfWriter &DW) { + Size = 0; + for (unsigned i = 0, N = Values.size(); i < N; ++i) { + Size += Values[i]->SizeOf(DW, Forms[i]); + } + return Size; +} + +/// BestForm - Choose the best form for data. +/// +unsigned DIEBlock::BestForm() { + if ((unsigned char)Size == Size) return DW_FORM_block1; + if ((unsigned short)Size == Size) return DW_FORM_block2; + if ((unsigned int)Size == Size) return DW_FORM_block4; + return DW_FORM_block; +} + +/// EmitValue - Emit block data. +/// +void DIEBlock::EmitValue(const DwarfWriter &DW, unsigned Form) const { + switch (Form) { + case DW_FORM_block1: DW.EmitInt8(Size); break; + case DW_FORM_block2: DW.EmitInt16(Size); break; + case DW_FORM_block4: DW.EmitInt32(Size); break; + case DW_FORM_block: DW.EmitULEB128Bytes(Size); break; + default: assert(0 && "Improper form for block"); break; + } + for (unsigned i = 0, N = Values.size(); i < N; ++i) { + DW.EOL(""); + Values[i]->EmitValue(DW, Forms[i]); + } +} + +/// SizeOf - Determine size of block data in bytes. +/// +unsigned DIEBlock::SizeOf(const DwarfWriter &DW, unsigned Form) const { + switch (Form) { + case DW_FORM_block1: return Size + sizeof(int8_t); + case DW_FORM_block2: return Size + sizeof(int16_t); + case DW_FORM_block4: return Size + sizeof(int32_t); + case DW_FORM_block: return Size + DW.SizeULEB128(Size); + default: assert(0 && "Improper form for block"); break; + } + return 0; +} + +/// AddUInt - Add an unsigned integer value. +/// +void DIEBlock::AddUInt(unsigned Form, uint64_t Integer) { + DIEInteger *DI = new DIEInteger(Integer); + Values.push_back(DI); + if (Form == 0) Form = DI->BestForm(false); + Forms.push_back(Form); +} + +/// AddSInt - Add an signed integer value. +/// +void DIEBlock::AddSInt(unsigned Form, int64_t Integer) { + DIEInteger *DI = new DIEInteger(Integer); + Values.push_back(DI); + if (Form == 0) Form = DI->BestForm(true); + Forms.push_back(Form); +} + +/// AddString - Add a std::string value. +/// +void DIEBlock::AddString(unsigned Form, const std::string &String) { + Values.push_back(new DIEString(String)); + Forms.push_back(Form); +} + +/// AddLabel - Add a Dwarf label value. +/// +void DIEBlock::AddLabel(unsigned Form, const DWLabel &Label) { + Values.push_back(new DIEDwarfLabel(Label)); + Forms.push_back(Form); +} + +/// AddObjectLabel - Add a non-Dwarf label value. +/// +void DIEBlock::AddObjectLabel(unsigned Form, const std::string &Label) { + Values.push_back(new DIEObjectLabel(Label)); + Forms.push_back(Form); +} + +/// AddDelta - Add a label delta value. +/// +void DIEBlock::AddDelta(unsigned Form, const DWLabel &Hi, const DWLabel &Lo) { + Values.push_back(new DIEDelta(Hi, Lo)); + Forms.push_back(Form); +} + +/// AddDIEntry - Add a DIE value. +/// +void DIEBlock::AddDIEntry(unsigned Form, DIE *Entry) { + Values.push_back(new DIEntry(Entry)); + Forms.push_back(Form); +} + +//===----------------------------------------------------------------------===// + DIE::DIE(unsigned Tag) : Abbrev(new DIEAbbrev(Tag, DW_CHILDREN_no)) , AbbrevID(0) @@ -637,67 +821,67 @@ /// AddUInt - Add an unsigned integer attribute data and value. /// void DIE::AddUInt(unsigned Attribute, unsigned Form, uint64_t Integer) { - if (Form == 0) { - if ((unsigned char)Integer == Integer) Form = DW_FORM_data1; - else if ((unsigned short)Integer == Integer) Form = DW_FORM_data2; - else if ((unsigned int)Integer == Integer) Form = DW_FORM_data4; - else Form = DW_FORM_data8; - } + DIEInteger *DI = new DIEInteger(Integer); + Values.push_back(DI); + if (!Form) Form = DI->BestForm(false); Abbrev->AddAttribute(Attribute, Form); - Values.push_back(new DIEInteger(Integer)); } /// AddSInt - Add an signed integer attribute data and value. /// void DIE::AddSInt(unsigned Attribute, unsigned Form, int64_t Integer) { - if (Form == 0) { - if ((char)Integer == Integer) Form = DW_FORM_data1; - else if ((short)Integer == Integer) Form = DW_FORM_data2; - else if ((int)Integer == Integer) Form = DW_FORM_data4; - else Form = DW_FORM_data8; - } + DIEInteger *DI = new DIEInteger(Integer); + Values.push_back(DI); + if (!Form) Form = DI->BestForm(true); Abbrev->AddAttribute(Attribute, Form); - Values.push_back(new DIEInteger(Integer)); } /// AddString - Add a std::string attribute data and value. /// void DIE::AddString(unsigned Attribute, unsigned Form, const std::string &String) { - Abbrev->AddAttribute(Attribute, Form); Values.push_back(new DIEString(String)); + Abbrev->AddAttribute(Attribute, Form); } /// AddLabel - Add a Dwarf label attribute data and value. /// void DIE::AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label) { - Abbrev->AddAttribute(Attribute, Form); Values.push_back(new DIEDwarfLabel(Label)); + Abbrev->AddAttribute(Attribute, Form); } /// AddObjectLabel - Add an non-Dwarf label attribute data and value. /// void DIE::AddObjectLabel(unsigned Attribute, unsigned Form, const std::string &Label) { - Abbrev->AddAttribute(Attribute, Form); Values.push_back(new DIEObjectLabel(Label)); + Abbrev->AddAttribute(Attribute, Form); } /// AddDelta - Add a label delta attribute data and value. /// void DIE::AddDelta(unsigned Attribute, unsigned Form, const DWLabel &Hi, const DWLabel &Lo) { - Abbrev->AddAttribute(Attribute, Form); Values.push_back(new DIEDelta(Hi, Lo)); + Abbrev->AddAttribute(Attribute, Form); } /// AddDIEntry - Add a DIE attribute data and value. /// -void DIE::AddDIEntry(unsigned Attribute, - unsigned Form, DIE *Entry) { - Abbrev->AddAttribute(Attribute, Form); +void DIE::AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry) { Values.push_back(new DIEntry(Entry)); + Abbrev->AddAttribute(Attribute, Form); +} + +/// AddBlock - Add block data. +/// +void DIE::AddBlock(unsigned Attribute, unsigned Form, DIEBlock *Block) { + assert(Block->Size && "Block size has not been computed"); + Values.push_back(Block); + if (!Form) Form = Block->BestForm(); + Abbrev->AddAttribute(Attribute, Form); } /// Complete - Indicate that all attributes have been added and ready to get an @@ -731,7 +915,7 @@ /// EOL - Print a newline character to asm stream. If a comment is present /// then it will be printed first. Comments should not contain '\n'. void DwarfWriter::EOL(const std::string &Comment) const { - if (DwarfVerbose) { + if (DwarfVerbose && !Comment.empty()) { O << "\t" << Asm->CommentString << " " @@ -1134,13 +1318,18 @@ // Add elements to structure type. for(unsigned i = 0, N = Elements.size(); i < N; ++i) { DerivedTypeDesc *MemberDesc = cast(Elements[i]); + + // Extract the basic information. const std::string &Name = MemberDesc->getName(); unsigned Line = MemberDesc->getLine(); TypeDesc *MemTy = MemberDesc->getFromType(); uint64_t Size = MemberDesc->getSize(); uint64_t Offset = MemberDesc->getOffset(); + // Construct member die. DIE *Member = new DIE(DW_TAG_member); + + // Add details. if (!Name.empty()) Member->AddString(DW_AT_name, DW_FORM_string, Name); if (CompileUnitDesc *File = MemberDesc->getFile()) { CompileUnit *FileUnit = FindCompileUnit(File); @@ -1149,13 +1338,19 @@ Member->AddUInt(DW_AT_decl_file, 0, FileID); Member->AddUInt(DW_AT_decl_line, 0, Line); } + if (TypeDesc *FromTy = MemberDesc->getFromType()) { Member->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy)); } - // FIXME - Punt on the Address. - Member->AddUInt(DW_AT_data_member_location, DW_FORM_block1, - Offset >> 3); + + // Add computation for offset. + DIEBlock *Block = new DIEBlock(); + Block->AddUInt(DW_FORM_data1, DW_OP_plus_uconst); + Block->AddUInt(DW_FORM_udata, Offset >> 3); + Block->ComputeSize(*this); + Member->AddBlock(DW_AT_data_member_location, 0, Block); + Ty->AddChild(Member); } break; @@ -1263,8 +1458,12 @@ VariableDie->AddUInt (DW_AT_decl_line, 0, Line); VariableDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type); VariableDie->AddUInt (DW_AT_external, DW_FORM_flag, 1); - // FIXME - needs to be a proper expression. - VariableDie->AddObjectLabel(DW_AT_location, DW_FORM_block1, MangledName); + + DIEBlock *Block = new DIEBlock(); + Block->AddUInt(DW_FORM_data1, DW_OP_addr); + Block->AddObjectLabel(DW_FORM_udata, MangledName); + Block->ComputeSize(*this); + VariableDie->AddBlock(DW_AT_location, 0, Block); // Add to map. Slot = VariableDie; From lattner at cs.uiuc.edu Fri Mar 3 18:02:22 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 18:02:22 -0600 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200603040002.SAA30735@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.137 -> 1.138 --- Log message: Spec change: the size of a memset/memcpy/memmove is not required to be aligned to the alignment argument. --- Diffs of the changes: (+6 -7) LangRef.html | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.137 llvm/docs/LangRef.html:1.138 --- llvm/docs/LangRef.html:1.137 Thu Mar 2 18:19:58 2006 +++ llvm/docs/LangRef.html Fri Mar 3 18:02:10 2006 @@ -3312,8 +3312,8 @@

          If the call to this intrinisic has an alignment value that is not 0 or 1, then -the caller guarantees that the size of the copy is a multiple of the alignment -and that both the source and destination pointers are aligned to that boundary. +the caller guarantees that both the source and destination pointers are aligned +to that boundary.

          Semantics:
          @@ -3367,8 +3367,8 @@

          If the call to this intrinisic has an alignment value that is not 0 or 1, then -the caller guarantees that the size of the copy is a multiple of the alignment -and that both the source and destination pointers are aligned to that boundary. +the caller guarantees that the source and destination pointers are aligned to +that boundary.

          Semantics:
          @@ -3421,8 +3421,7 @@

          If the call to this intrinisic has an alignment value that is not 0 or 1, then -the caller guarantees that the size of the copy is a multiple of the alignment -and that the destination pointer is aligned to that boundary. +the caller guarantees that the destination pointer is aligned to that boundary.

          Semantics:
          @@ -3695,7 +3694,7 @@ Chris Lattner
          The LLVM Compiler Infrastructure
          - Last modified: $Date: 2006/03/03 00:19:58 $ + Last modified: $Date: 2006/03/04 00:02:10 $ From lattner at cs.uiuc.edu Fri Mar 3 18:47:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 18:47:25 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2006-03-03-MissingInitializer.c Message-ID: <200603040047.SAA31101@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2006-03-03-MissingInitializer.c added (r1.1) --- Log message: New testcase, make sure nate doesn't vanish --- Diffs of the changes: (+10 -0) 2006-03-03-MissingInitializer.c | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/CFrontend/2006-03-03-MissingInitializer.c diff -c /dev/null llvm/test/Regression/CFrontend/2006-03-03-MissingInitializer.c:1.1 *** /dev/null Fri Mar 3 18:47:22 2006 --- llvm/test/Regression/CFrontend/2006-03-03-MissingInitializer.c Fri Mar 3 18:47:12 2006 *************** *** 0 **** --- 1,10 ---- + // RUN: %llvmgcc %s -S -o - | gccas | llvm-dis | grep nate | grep 'global int 0' + + struct X { int *XX; int Y;}; + + void foo() { + static int nate = 0; + struct X bob = { &nate, 14 }; + bar(&bob); + } + From evan.cheng at apple.com Fri Mar 3 19:12:12 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Mar 2006 19:12:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200603040112.TAA31369@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.99 -> 1.100 --- Log message: Typo --- Diffs of the changes: (+2 -2) X86ISelLowering.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.99 llvm/lib/Target/X86/X86ISelLowering.cpp:1.100 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.99 Thu Mar 2 18:19:44 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 3 19:12:00 2006 @@ -1997,8 +1997,8 @@ case X86ISD::CMOV: return "X86ISD::CMOV"; case X86ISD::BRCOND: return "X86ISD::BRCOND"; case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG"; - case X86ISD::REP_STOS: return "X86ISD::RET_STOS"; - case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS"; + case X86ISD::REP_STOS: return "X86ISD::REP_STOS"; + case X86ISD::REP_MOVS: return "X86ISD::REP_MOVS"; case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK"; case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg"; case X86ISD::Wrapper: return "X86ISD::Wrapper"; From lattner at cs.uiuc.edu Fri Mar 3 19:19:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 19:19:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603040119.TAA31443@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.9 -> 1.10 --- Log message: add a note --- Diffs of the changes: (+15 -0) README.txt | 15 +++++++++++++++ 1 files changed, 15 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.9 llvm/lib/Target/README.txt:1.10 --- llvm/lib/Target/README.txt:1.9 Thu Mar 2 16:34:38 2006 +++ llvm/lib/Target/README.txt Fri Mar 3 19:19:34 2006 @@ -86,3 +86,18 @@ into: int f(int a, int b) { return a * (a + 2 * b) + b * b; } to eliminate a multiply. + +//===---------------------------------------------------------------------===// + +On targets with expensive 64-bit multiply, we could LSR this: + +for (i = ...; ++i) { + x = 1ULL << i; + +into: + long long tmp = 1; + for (i = ...; ++i, tmp+=tmp) + x = tmp; + +This would be a win on ppc32, but not x86 or ppc64. + From lattner at cs.uiuc.edu Fri Mar 3 20:05:19 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 20:05:19 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll Message-ID: <200603040205.UAA31893@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/BasicAA: 2006-03-03-BadArraySubscript.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+31 -0) 2006-03-03-BadArraySubscript.ll | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+) Index: llvm/test/Regression/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll diff -c /dev/null llvm/test/Regression/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll:1.1 *** /dev/null Fri Mar 3 20:05:17 2006 --- llvm/test/Regression/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll Fri Mar 3 20:05:07 2006 *************** *** 0 **** --- 1,31 ---- + ; RUN: llvm-as < %s | opt -aa-eval -disable-output 2>&1 | grep '2 no alias respon' + + ;; TEST that A[1][0] may alias A[0][i]. + + void %test(int %N) { + entry: + %X = alloca [3 x [3 x int]] ; <[3 x [3 x int]]*> [#uses=4] + %tmp.24 = setgt int %N, 0 ; [#uses=1] + br bool %tmp.24, label %no_exit, label %loopexit + + no_exit: ; preds = %no_exit, %entry + %i.0.0 = phi int [ 0, %entry ], [ %inc, %no_exit ] ; [#uses=2] + %tmp.6 = getelementptr [3 x [3 x int]]* %X, int 0, int 0, int %i.0.0 ; [#uses=1] + store int 1, int* %tmp.6 + %tmp.8 = getelementptr [3 x [3 x int]]* %X, int 0, int 0, int 0 ; [#uses=1] + %tmp.9 = load int* %tmp.8 ; [#uses=1] + %tmp.11 = getelementptr [3 x [3 x int]]* %X, int 0, int 1, int 0 ; [#uses=1] + %tmp.12 = load int* %tmp.11 ; [#uses=1] + %tmp.13 = add int %tmp.12, %tmp.9 ; [#uses=1] + %inc = add int %i.0.0, 1 ; [#uses=2] + %tmp.2 = setlt int %inc, %N ; [#uses=1] + br bool %tmp.2, label %no_exit, label %loopexit + + loopexit: ; preds = %no_exit, %entry + %Y.0.1 = phi int [ 0, %entry ], [ %tmp.13, %no_exit ] ; [#uses=1] + %tmp.4 = getelementptr [3 x [3 x int]]* %X, int 0, int 0 ; <[3 x int]*> [#uses=1] + %tmp.15 = call int (...)* %foo( [3 x int]* %tmp.4, int %Y.0.1 ) ; [#uses=0] + ret void + } + + declare int %foo(...) From lattner at cs.uiuc.edu Fri Mar 3 20:06:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Mar 2006 20:06:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200603040206.UAA31909@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.76 -> 1.77 --- Log message: Be more conservative with our symbolic alias analysis. In particular, don't assume that A[1][0] and A[0][i] can't alias. "i" might be out of range, or even negative. This fixes a miscompilation of 188.ammp (which does bad pointer tricks) with the new CFE. Testcase here: Analysis/BasicAA/2006-03-03-BadArraySubscript.ll --- Diffs of the changes: (+35 -6) BasicAliasAnalysis.cpp | 41 +++++++++++++++++++++++++++++++++++------ 1 files changed, 35 insertions(+), 6 deletions(-) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.76 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.77 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.76 Fri Jan 13 19:25:24 2006 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Fri Mar 3 20:06:34 2006 @@ -527,6 +527,14 @@ // chain. For example: // A[i][0] != A[j][1] iff (&A[0][1]-&A[0][0] >= std::max(G1S, G2S)) // + // We have to be careful here about array accesses. In particular, consider: + // A[1][0] vs A[0][i] + // In this case, we don't *know* that the array will be accessed in bounds: + // the index could even be negative. Because of this, we have to + // conservatively *give up* and return may alias. We disregard differing + // array subscripts that are followed by a variable index without going + // through a struct. + // unsigned SizeMax = std::max(G1S, G2S); if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work. @@ -547,15 +555,36 @@ GEP1Ops[FirstConstantOper] = G1OC; GEP2Ops[FirstConstantOper] = G2OC; } - + if (G1OC != G2OC) { + // Handle the "be careful" case above: if this is an array + // subscript, scan for a subsequent variable array index. + if (isa(BasePtr1Ty)) { + const Type *NextTy =cast(BasePtr1Ty)->getElementType(); + bool isBadCase = false; + + for (unsigned Idx = FirstConstantOper+1; + Idx != MinOperands && isa(NextTy); ++Idx) { + const Value *V1 = GEP1Ops[Idx], *V2 = GEP2Ops[Idx]; + if (!isa(V1) || !isa(V2)) { + isBadCase = true; + break; + } + NextTy = cast(NextTy)->getElementType(); + } + + if (isBadCase) G1OC = 0; + } + // Make sure they are comparable (ie, not constant expressions), and // make sure the GEP with the smaller leading constant is GEP1. - Constant *Compare = ConstantExpr::getSetGT(G1OC, G2OC); - if (ConstantBool *CV = dyn_cast(Compare)) { - if (CV->getValue()) // If they are comparable and G2 > G1 - std::swap(GEP1Ops, GEP2Ops); // Make GEP1 < GEP2 - break; + if (G1OC) { + Constant *Compare = ConstantExpr::getSetGT(G1OC, G2OC); + if (ConstantBool *CV = dyn_cast(Compare)) { + if (CV->getValue()) // If they are comparable and G2 > G1 + std::swap(GEP1Ops, GEP2Ops); // Make GEP1 < GEP2 + break; + } } } } From jeffc at jolt-lang.org Fri Mar 3 20:19:59 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 3 Mar 2006 20:19:59 -0600 Subject: [llvm-commits] CVS: llvm/win32/x86/x86.vcproj Message-ID: <200603040219.UAA31999@zion.cs.uiuc.edu> Changes in directory llvm/win32/x86: x86.vcproj updated: 1.21 -> 1.22 --- Log message: Keep Visual Studio happy. --- Diffs of the changes: (+18 -20) x86.vcproj | 38 ++++++++++++++++++-------------------- 1 files changed, 18 insertions(+), 20 deletions(-) Index: llvm/win32/x86/x86.vcproj diff -u llvm/win32/x86/x86.vcproj:1.21 llvm/win32/x86/x86.vcproj:1.22 --- llvm/win32/x86/x86.vcproj:1.21 Thu Feb 16 20:11:34 2006 +++ llvm/win32/x86/x86.vcproj Fri Mar 3 20:19:46 2006 @@ -116,16 +116,15 @@ @@ -134,16 +133,15 @@ From jeffc at jolt-lang.org Fri Mar 3 20:19:59 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 3 Mar 2006 20:19:59 -0600 Subject: [llvm-commits] CVS: llvm/win32/TableGen/TableGen.vcproj Message-ID: <200603040219.UAA31995@zion.cs.uiuc.edu> Changes in directory llvm/win32/TableGen: TableGen.vcproj updated: 1.20 -> 1.21 --- Log message: Keep Visual Studio happy. --- Diffs of the changes: (+18 -5) TableGen.vcproj | 23 ++++++++++++++++++----- 1 files changed, 18 insertions(+), 5 deletions(-) Index: llvm/win32/TableGen/TableGen.vcproj diff -u llvm/win32/TableGen/TableGen.vcproj:1.20 llvm/win32/TableGen/TableGen.vcproj:1.21 --- llvm/win32/TableGen/TableGen.vcproj:1.20 Sun Jan 29 22:07:07 2006 +++ llvm/win32/TableGen/TableGen.vcproj Fri Mar 3 20:19:46 2006 @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\include;..;..\..\utils\tablegen" - PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;__STDC_LIMIT_MACROS" + PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;__STDC_LIMIT_MACROS" StringPooling="TRUE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" @@ -144,7 +144,8 @@ @@ -163,7 +165,8 @@ @@ -179,6 +183,9 @@ RelativePath="..\..\utils\TableGen\InstrInfoEmitter.cpp"> + + + + + + Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.100 -> 1.101 --- Log message: MEMSET / MEMCPY lowering bugs: we can't issue a single WORD / DWORD version of rep/stos and rep/mov if the count is not a constant. We could do rep/stosl; and $count, 3; rep/stosb For now, I will lower them to memset / memcpy calls. We will revisit this after a little bit experiment. Also need to take care of the trailing bytes even if the count is a constant. Since the max. number of trailing bytes are 3, we will simply issue loads / stores. --- Diffs of the changes: (+83 -28) X86ISelLowering.cpp | 111 ++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 83 insertions(+), 28 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.100 llvm/lib/Target/X86/X86ISelLowering.cpp:1.101 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.100 Fri Mar 3 19:12:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 3 20:48:56 2006 @@ -1696,7 +1696,7 @@ Op.getOperand(0), Op.getOperand(2), CC, Cond); } case ISD::MEMSET: { - SDOperand InFlag; + SDOperand InFlag(0, 0); SDOperand Chain = Op.getOperand(0); unsigned Align = (unsigned)cast(Op.getOperand(4))->getValue(); @@ -1705,7 +1705,7 @@ ConstantSDNode *I = dyn_cast(Op.getOperand(3)); // If not DWORD aligned, call memset if size is less than the threshold. // It knows how to align to the right boundary first. - if ((Align & 3) != 0 && + if ((Align & 3) != 0 || !(I && I->getValue() >= Subtarget->getMinRepStrSizeThreshold())) { MVT::ValueType IntPtr = getPointerTy(); const Type *IntPtrTy = getTargetData().getIntPtrType(); @@ -1723,7 +1723,9 @@ MVT::ValueType AVT; SDOperand Count; - if (ConstantSDNode *ValC = dyn_cast(Op.getOperand(2))) { + ConstantSDNode *ValC = dyn_cast(Op.getOperand(2)); + unsigned BytesLeft = 0; + if (ValC) { unsigned ValReg; unsigned Val = ValC->getValue() & 255; @@ -1731,21 +1733,15 @@ switch (Align & 3) { case 2: // WORD aligned AVT = MVT::i16; - if (I) - Count = DAG.getConstant(I->getValue() / 2, MVT::i32); - else - Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3), - DAG.getConstant(1, MVT::i8)); + Count = DAG.getConstant(I->getValue() / 2, MVT::i32); + BytesLeft = I->getValue() % 2; Val = (Val << 8) | Val; ValReg = X86::AX; break; case 0: // DWORD aligned AVT = MVT::i32; - if (I) - Count = DAG.getConstant(I->getValue() / 4, MVT::i32); - else - Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3), - DAG.getConstant(2, MVT::i8)); + Count = DAG.getConstant(I->getValue() / 4, MVT::i32); + BytesLeft = I->getValue() % 4; Val = (Val << 8) | Val; Val = (Val << 16) | Val; ValReg = X86::EAX; @@ -1771,9 +1767,36 @@ InFlag = Chain.getValue(1); Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag); InFlag = Chain.getValue(1); + Chain = DAG.getNode(X86ISD::REP_STOS, MVT::Other, Chain, + DAG.getValueType(AVT), InFlag); + + if (BytesLeft) { + // Issue stores for the last 1 - 3 bytes. + SDOperand Value; + unsigned Val = ValC->getValue() & 255; + unsigned Offset = I->getValue() - BytesLeft; + SDOperand DstAddr = Op.getOperand(1); + MVT::ValueType AddrVT = DstAddr.getValueType(); + if (BytesLeft >= 2) { + Value = DAG.getConstant((Val << 8) | Val, MVT::i16); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, + DAG.getNode(ISD::ADD, AddrVT, DstAddr, + DAG.getConstant(Offset, AddrVT)), + DAG.getSrcValue(NULL)); + BytesLeft -= 2; + Offset += 2; + } + + if (BytesLeft == 1) { + Value = DAG.getConstant(Val, MVT::i8); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, + DAG.getNode(ISD::ADD, AddrVT, DstAddr, + DAG.getConstant(Offset, AddrVT)), + DAG.getSrcValue(NULL)); + } + } - return DAG.getNode(X86ISD::REP_STOS, MVT::Other, Chain, - DAG.getValueType(AVT), InFlag); + return Chain; } case ISD::MEMCPY: { SDOperand Chain = Op.getOperand(0); @@ -1784,7 +1807,7 @@ ConstantSDNode *I = dyn_cast(Op.getOperand(3)); // If not DWORD aligned, call memcpy if size is less than the threshold. // It knows how to align to the right boundary first. - if ((Align & 3) != 0 && + if ((Align & 3) != 0 || !(I && I->getValue() >= Subtarget->getMinRepStrSizeThreshold())) { MVT::ValueType IntPtr = getPointerTy(); const Type *IntPtrTy = getTargetData().getIntPtrType(); @@ -1800,21 +1823,17 @@ MVT::ValueType AVT; SDOperand Count; + unsigned BytesLeft = 0; switch (Align & 3) { case 2: // WORD aligned AVT = MVT::i16; - if (I) - Count = DAG.getConstant(I->getValue() / 2, MVT::i32); - else - Count = DAG.getConstant(I->getValue() / 2, MVT::i32); + Count = DAG.getConstant(I->getValue() / 2, MVT::i32); + BytesLeft = I->getValue() % 2; break; case 0: // DWORD aligned AVT = MVT::i32; - if (I) - Count = DAG.getConstant(I->getValue() / 4, MVT::i32); - else - Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3), - DAG.getConstant(2, MVT::i8)); + Count = DAG.getConstant(I->getValue() / 4, MVT::i32); + BytesLeft = I->getValue() % 4; break; default: // Byte aligned AVT = MVT::i8; @@ -1822,16 +1841,52 @@ break; } - SDOperand InFlag; + SDOperand InFlag(0, 0); Chain = DAG.getCopyToReg(Chain, X86::ECX, Count, InFlag); InFlag = Chain.getValue(1); Chain = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag); InFlag = Chain.getValue(1); Chain = DAG.getCopyToReg(Chain, X86::ESI, Op.getOperand(2), InFlag); InFlag = Chain.getValue(1); + Chain = DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain, + DAG.getValueType(AVT), InFlag); + + if (BytesLeft) { + // Issue loads and stores for the last 1 - 3 bytes. + unsigned Offset = I->getValue() - BytesLeft; + SDOperand DstAddr = Op.getOperand(1); + MVT::ValueType DstVT = DstAddr.getValueType(); + SDOperand SrcAddr = Op.getOperand(2); + MVT::ValueType SrcVT = SrcAddr.getValueType(); + SDOperand Value; + if (BytesLeft >= 2) { + Value = DAG.getLoad(MVT::i16, Chain, + DAG.getNode(ISD::ADD, SrcVT, SrcAddr, + DAG.getConstant(Offset, SrcVT)), + DAG.getSrcValue(NULL)); + Chain = Value.getValue(1); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, + DAG.getNode(ISD::ADD, DstVT, DstAddr, + DAG.getConstant(Offset, DstVT)), + DAG.getSrcValue(NULL)); + BytesLeft -= 2; + Offset += 2; + } + + if (BytesLeft == 1) { + Value = DAG.getLoad(MVT::i8, Chain, + DAG.getNode(ISD::ADD, SrcVT, SrcAddr, + DAG.getConstant(Offset, SrcVT)), + DAG.getSrcValue(NULL)); + Chain = Value.getValue(1); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, + DAG.getNode(ISD::ADD, DstVT, DstAddr, + DAG.getConstant(Offset, DstVT)), + DAG.getSrcValue(NULL)); + } + } - return DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain, - DAG.getValueType(AVT), InFlag); + return Chain; } // ConstantPool, GlobalAddress, and ExternalSymbol are lowered as their From lattner at cs.uiuc.edu Sat Mar 4 00:02:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 00:02:48 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll Message-ID: <200603040602.AAA00753@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.28 -> 1.29 --- Log message: new testcase --- Diffs of the changes: (+7 -0) add.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.28 llvm/test/Regression/Transforms/InstCombine/add.ll:1.29 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.28 Wed Nov 2 12:34:05 2005 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Sat Mar 4 00:02:36 2006 @@ -213,3 +213,10 @@ %tmp.4 = add long %tmp.2, -9223372036854775808 ret long %tmp.4 } + +int %test31(int %A) { + %B = add int %A, 4 + %C = mul int %B, 5 + %D = sub int %C, 20 + ret int %D +} From lattner at cs.uiuc.edu Sat Mar 4 00:04:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 00:04:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200603040604.AAA00787@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.447 -> 1.448 --- Log message: Canonicalize (X+C1)*C2 -> X*C2+C1*C2 This implements Transforms/InstCombine/add.ll:test31 --- Diffs of the changes: (+13 -0) InstructionCombining.cpp | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.447 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.448 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.447 Thu Mar 2 19:34:17 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Mar 4 00:04:02 2006 @@ -1622,6 +1622,19 @@ if (Op1F->getValue() == 1.0) return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0' } + + if (BinaryOperator *Op0I = dyn_cast(Op0)) + if (Op0I->getOpcode() == Instruction::Add && Op0I->hasOneUse() && + isa(Op0I->getOperand(1))) { + // Canonicalize (X+C1)*C2 -> X*C2+C1*C2. + Instruction *Add = BinaryOperator::createMul(Op0I->getOperand(0), + Op1, "tmp"); + InsertNewInstBefore(Add, I); + Value *C1C2 = ConstantExpr::getMul(Op1, + cast(Op0I->getOperand(1))); + return BinaryOperator::createAdd(Add, C1C2); + + } // Try to fold constant mul into select arguments. if (SelectInst *SI = dyn_cast(Op0)) From evan.cheng at apple.com Sat Mar 4 01:50:03 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Mar 2006 01:50:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200603040750.BAA01342@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.62 -> 1.63 --- Log message: Add an entry --- Diffs of the changes: (+5 -0) README.txt | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.62 llvm/lib/Target/X86/README.txt:1.63 --- llvm/lib/Target/X86/README.txt:1.62 Tue Feb 28 17:38:49 2006 +++ llvm/lib/Target/X86/README.txt Sat Mar 4 01:49:50 2006 @@ -533,3 +533,8 @@ imull $9, 4(%esp), %eax Currently the load folding imull has a higher complexity than the LEA32 pattern. + +//===---------------------------------------------------------------------===// + +Lower memcpy / memset to a series of SSE 128 bit move instructions when it's +feasible. From lattner at cs.uiuc.edu Sat Mar 4 01:53:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 01:53:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200603040753.BAA01411@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.249 -> 1.250 --- Log message: Don't use invalidated iterators! --- Diffs of the changes: (+3 -3) llvmAsmParser.y | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.249 llvm/lib/AsmParser/llvmAsmParser.y:1.250 --- llvm/lib/AsmParser/llvmAsmParser.y:1.249 Wed Jan 25 16:26:43 2006 +++ llvm/lib/AsmParser/llvmAsmParser.y Sat Mar 4 01:53:16 2006 @@ -107,9 +107,9 @@ } // Look for intrinsic functions and CallInst that need to be upgraded - for (Module::iterator FI = CurrentModule->begin(),FE = CurrentModule->end(); - FI != FE; ++FI) - UpgradeCallsToIntrinsic(FI); + for (Module::iterator FI = CurrentModule->begin(), + FE = CurrentModule->end(); FI != FE; ) + UpgradeCallsToIntrinsic(FI++); Values.clear(); // Clear out function local definitions Types.clear(); From lattner at cs.uiuc.edu Sat Mar 4 01:53:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 01:53:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.cpp.cvs llvmAsmParser.y.cvs Message-ID: <200603040753.BAA01449@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.cpp.cvs updated: 1.1 -> 1.2 llvmAsmParser.y.cvs updated: 1.1 -> 1.2 --- Log message: Regenerate --- Diffs of the changes: (+185 -185) llvmAsmParser.cpp.cvs | 366 +++++++++++++++++++++++++------------------------- llvmAsmParser.y.cvs | 4 2 files changed, 185 insertions(+), 185 deletions(-) Index: llvm/lib/AsmParser/llvmAsmParser.cpp.cvs diff -u llvm/lib/AsmParser/llvmAsmParser.cpp.cvs:1.1 llvm/lib/AsmParser/llvmAsmParser.cpp.cvs:1.2 --- llvm/lib/AsmParser/llvmAsmParser.cpp.cvs:1.1 Wed Feb 15 01:22:58 2006 +++ llvm/lib/AsmParser/llvmAsmParser.cpp.cvs Sat Mar 4 01:53:40 2006 @@ -1,5 +1,5 @@ -/* A Bison parser, made from /Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y +/* A Bison parser, made from /Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y by GNU Bison version 1.28 */ #define YYBISON 1 /* Identify Bison output. */ @@ -110,7 +110,7 @@ #define VAARG_old 353 #define VANEXT_old 354 -#line 14 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 14 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -208,8 +208,8 @@ // Look for intrinsic functions and CallInst that need to be upgraded for (Module::iterator FI = CurrentModule->begin(),FE = CurrentModule->end(); - FI != FE; ++FI) - UpgradeCallsToIntrinsic(FI); + FI != FE; ) + UpgradeCallsToIntrinsic(FI++); Values.clear(); // Clear out function local definitions Types.clear(); @@ -986,7 +986,7 @@ } -#line 890 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 890 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" typedef union { llvm::Module *ModuleVal; llvm::Function *FunctionVal; @@ -2226,7 +2226,7 @@ switch (yyn) { case 2: -#line 1011 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1011 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UIntVal > (uint32_t)INT32_MAX) // Outside of my range! ThrowException("Value too large for type!"); @@ -2234,7 +2234,7 @@ ; break;} case 4: -#line 1019 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1019 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UInt64Val > (uint64_t)INT64_MAX) // Outside of my range! ThrowException("Value too large for type!"); @@ -2242,55 +2242,55 @@ ; break;} case 33: -#line 1042 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1042 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = yyvsp[-1].StrVal; ; break;} case 34: -#line 1045 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1045 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = 0; ; break;} case 35: -#line 1049 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1049 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::InternalLinkage; ; break;} case 36: -#line 1050 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1050 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::LinkOnceLinkage; ; break;} case 37: -#line 1051 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1051 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::WeakLinkage; ; break;} case 38: -#line 1052 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1052 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::AppendingLinkage; ; break;} case 39: -#line 1053 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1053 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Linkage = GlobalValue::ExternalLinkage; ; break;} case 40: -#line 1055 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1055 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::C; ; break;} case 41: -#line 1056 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1056 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::C; ; break;} case 42: -#line 1057 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1057 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::Fast; ; break;} case 43: -#line 1058 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1058 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = CallingConv::Cold; ; break;} case 44: -#line 1059 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1059 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if ((unsigned)yyvsp[0].UInt64Val != yyvsp[0].UInt64Val) ThrowException("Calling conv too large!"); @@ -2298,11 +2298,11 @@ ; break;} case 45: -#line 1067 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1067 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = 0; ; break;} case 46: -#line 1068 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1068 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = yyvsp[0].UInt64Val; if (yyval.UIntVal != 0 && !isPowerOf2_32(yyval.UIntVal)) @@ -2310,11 +2310,11 @@ ; break;} case 47: -#line 1073 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1073 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = 0; ; break;} case 48: -#line 1074 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1074 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.UIntVal = yyvsp[0].UInt64Val; if (yyval.UIntVal != 0 && !isPowerOf2_32(yyval.UIntVal)) @@ -2322,7 +2322,7 @@ ; break;} case 49: -#line 1081 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1081 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { for (unsigned i = 0, e = strlen(yyvsp[0].StrVal); i != e; ++i) if (yyvsp[0].StrVal[i] == '"' || yyvsp[0].StrVal[i] == '\\') @@ -2331,30 +2331,30 @@ ; break;} case 50: -#line 1088 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1088 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = 0; ; break;} case 51: -#line 1089 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1089 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = yyvsp[0].StrVal; ; break;} case 52: -#line 1094 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1094 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" {; break;} case 53: -#line 1095 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1095 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" {; break;} case 54: -#line 1096 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1096 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV->setSection(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 55: -#line 1100 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1100 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UInt64Val != 0 && !isPowerOf2_32(yyvsp[0].UInt64Val)) ThrowException("Alignment must be a power of two!"); @@ -2362,15 +2362,15 @@ ; break;} case 57: -#line 1113 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1113 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; break;} case 59: -#line 1114 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1114 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; break;} case 60: -#line 1116 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1116 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) ThrowException("Invalid upreference in type: " + (*yyvsp[0].TypeVal)->getDescription()); @@ -2378,25 +2378,25 @@ ; break;} case 74: -#line 1127 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1127 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(OpaqueType::get()); ; break;} case 75: -#line 1130 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1130 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; break;} case 76: -#line 1133 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1133 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Named types are also simple types... yyval.TypeVal = new PATypeHolder(getTypeVal(yyvsp[0].ValIDVal)); ; break;} case 77: -#line 1139 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1139 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Type UpReference if (yyvsp[0].UInt64Val > (uint64_t)~0U) ThrowException("Value out of range!"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder @@ -2406,7 +2406,7 @@ ; break;} case 78: -#line 1146 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1146 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Function derived type? std::vector Params; for (std::list::iterator I = yyvsp[-1].TypeList->begin(), @@ -2421,14 +2421,14 @@ ; break;} case 79: -#line 1158 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1158 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Sized array type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(ArrayType::get(*yyvsp[-1].TypeVal, (unsigned)yyvsp[-3].UInt64Val))); delete yyvsp[-1].TypeVal; ; break;} case 80: -#line 1162 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1162 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Packed array type? const llvm::Type* ElemTy = yyvsp[-1].TypeVal->get(); if ((unsigned)yyvsp[-3].UInt64Val != yyvsp[-3].UInt64Val) @@ -2442,7 +2442,7 @@ ; break;} case 81: -#line 1173 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1173 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Structure type? std::vector Elements; for (std::list::iterator I = yyvsp[-1].TypeList->begin(), @@ -2454,51 +2454,51 @@ ; break;} case 82: -#line 1182 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1182 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? yyval.TypeVal = new PATypeHolder(StructType::get(std::vector())); ; break;} case 83: -#line 1185 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1185 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Pointer type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(PointerType::get(*yyvsp[-1].TypeVal))); delete yyvsp[-1].TypeVal; ; break;} case 84: -#line 1193 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1193 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeList = new std::list(); yyval.TypeList->push_back(*yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; ; break;} case 85: -#line 1197 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1197 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList=yyvsp[-2].TypeList)->push_back(*yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; ; break;} case 87: -#line 1203 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1203 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList=yyvsp[-2].TypeList)->push_back(Type::VoidTy); ; break;} case 88: -#line 1206 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1206 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.TypeList = new std::list())->push_back(Type::VoidTy); ; break;} case 89: -#line 1209 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1209 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TypeList = new std::list(); ; break;} case 90: -#line 1219 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1219 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr const ArrayType *ATy = dyn_cast(yyvsp[-3].TypeVal->get()); if (ATy == 0) @@ -2526,7 +2526,7 @@ ; break;} case 91: -#line 1244 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1244 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const ArrayType *ATy = dyn_cast(yyvsp[-2].TypeVal->get()); if (ATy == 0) @@ -2542,7 +2542,7 @@ ; break;} case 92: -#line 1257 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1257 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const ArrayType *ATy = dyn_cast(yyvsp[-2].TypeVal->get()); if (ATy == 0) @@ -2574,7 +2574,7 @@ ; break;} case 93: -#line 1286 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1286 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr const PackedType *PTy = dyn_cast(yyvsp[-3].TypeVal->get()); if (PTy == 0) @@ -2602,7 +2602,7 @@ ; break;} case 94: -#line 1311 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1311 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast(yyvsp[-3].TypeVal->get()); if (STy == 0) @@ -2625,7 +2625,7 @@ ; break;} case 95: -#line 1331 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1331 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const StructType *STy = dyn_cast(yyvsp[-2].TypeVal->get()); if (STy == 0) @@ -2640,7 +2640,7 @@ ; break;} case 96: -#line 1343 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1343 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PTy = dyn_cast(yyvsp[-1].TypeVal->get()); if (PTy == 0) @@ -2652,14 +2652,14 @@ ; break;} case 97: -#line 1352 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1352 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ConstVal = UndefValue::get(yyvsp[-1].TypeVal->get()); delete yyvsp[-1].TypeVal; ; break;} case 98: -#line 1356 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1356 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *Ty = dyn_cast(yyvsp[-1].TypeVal->get()); if (Ty == 0) @@ -2721,7 +2721,7 @@ ; break;} case 99: -#line 1415 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1415 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-1].TypeVal->get() != yyvsp[0].ConstVal->getType()) ThrowException("Mismatched types for constant expression!"); @@ -2730,7 +2730,7 @@ ; break;} case 100: -#line 1421 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1421 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = yyvsp[-1].TypeVal->get(); if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) @@ -2740,7 +2740,7 @@ ; break;} case 101: -#line 1429 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1429 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantSInt::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].SInt64Val)) ThrowException("Constant value doesn't fit in type!"); @@ -2748,7 +2748,7 @@ ; break;} case 102: -#line 1434 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1434 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // integral constants if (!ConstantUInt::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].UInt64Val)) ThrowException("Constant value doesn't fit in type!"); @@ -2756,19 +2756,19 @@ ; break;} case 103: -#line 1439 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1439 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Boolean constants yyval.ConstVal = ConstantBool::True; ; break;} case 104: -#line 1442 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1442 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Boolean constants yyval.ConstVal = ConstantBool::False; ; break;} case 105: -#line 1445 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1445 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Float & Double constants if (!ConstantFP::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].FPVal)) ThrowException("Floating point constant invalid for type!!"); @@ -2776,7 +2776,7 @@ ; break;} case 106: -#line 1452 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1452 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!yyvsp[-3].ConstVal->getType()->isFirstClassType()) ThrowException("cast constant expression from a non-primitive type: '" + @@ -2789,7 +2789,7 @@ ; break;} case 107: -#line 1462 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1462 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-2].ConstVal->getType())) ThrowException("GetElementPtr requires a pointer operand!"); @@ -2823,7 +2823,7 @@ ; break;} case 108: -#line 1493 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1493 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-5].ConstVal->getType() != Type::BoolTy) ThrowException("Select condition must be of boolean type!"); @@ -2833,7 +2833,7 @@ ; break;} case 109: -#line 1500 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1500 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Binary operator types must match!"); @@ -2857,7 +2857,7 @@ ; break;} case 110: -#line 1521 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1521 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Logical operator types must match!"); @@ -2870,7 +2870,7 @@ ; break;} case 111: -#line 1531 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1531 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("setcc operand types must match!"); @@ -2878,7 +2878,7 @@ ; break;} case 112: -#line 1536 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1536 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-1].ConstVal->getType() != Type::UByteTy) ThrowException("Shift count for shift constant must be unsigned byte!"); @@ -2888,7 +2888,7 @@ ; break;} case 113: -#line 1543 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1543 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-3].ConstVal->getType())) ThrowException("First operand of extractelement must be " @@ -2899,60 +2899,60 @@ ; break;} case 114: -#line 1553 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1553 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { (yyval.ConstVector = yyvsp[-2].ConstVector)->push_back(yyvsp[0].ConstVal); ; break;} case 115: -#line 1556 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1556 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ConstVector = new std::vector(); yyval.ConstVector->push_back(yyvsp[0].ConstVal); ; break;} case 116: -#line 1563 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1563 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 117: -#line 1563 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1563 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 118: -#line 1573 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1573 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = ParserResult = yyvsp[0].ModuleVal; CurModule.ModuleDone(); ; break;} case 119: -#line 1580 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1580 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-1].ModuleVal; CurFun.FunctionDone(); ; break;} case 120: -#line 1584 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1584 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-1].ModuleVal; ; break;} case 121: -#line 1587 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1587 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-3].ModuleVal; ; break;} case 122: -#line 1590 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1590 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = yyvsp[-1].ModuleVal; ; break;} case 123: -#line 1593 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1593 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ModuleVal = CurModule.CurrentModule; // Emit an error if there are any unresolved types left. @@ -2966,7 +2966,7 @@ ; break;} case 124: -#line 1606 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1606 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Eagerly resolve types. This is not an optimization, this is a // requirement that is due to the fact that we could have this: @@ -2989,30 +2989,30 @@ ; break;} case 125: -#line 1626 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1626 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Function prototypes can be in const pool ; break;} case 126: -#line 1628 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1628 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Asm blocks can be in the const pool ; break;} case 127: -#line 1630 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1630 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].ConstVal == 0) ThrowException("Global value initializer is not a constant!"); CurGV = ParseGlobalVariable(yyvsp[-3].StrVal, yyvsp[-2].Linkage, yyvsp[-1].BoolVal, yyvsp[0].ConstVal->getType(), yyvsp[0].ConstVal); ; break;} case 128: -#line 1633 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1633 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ; break;} case 129: -#line 1636 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1636 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV = ParseGlobalVariable(yyvsp[-3].StrVal, GlobalValue::ExternalLinkage, yyvsp[-1].BoolVal, *yyvsp[0].TypeVal, 0); @@ -3020,28 +3020,28 @@ ; break;} case 130: -#line 1640 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1640 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ; break;} case 131: -#line 1643 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1643 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 132: -#line 1645 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1645 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 133: -#line 1647 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1647 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 134: -#line 1651 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1651 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); char *EndStr = UnEscapeLexed(yyvsp[0].StrVal, true); @@ -3055,21 +3055,21 @@ ; break;} case 135: -#line 1663 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1663 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Endianness = Module::BigEndian; ; break;} case 136: -#line 1664 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1664 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.Endianness = Module::LittleEndian; ; break;} case 137: -#line 1666 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1666 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setEndianness(yyvsp[0].Endianness); ; break;} case 138: -#line 1669 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1669 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].UInt64Val == 32) CurModule.CurrentModule->setPointerSize(Module::Pointer32); @@ -3080,37 +3080,37 @@ ; break;} case 139: -#line 1677 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1677 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setTargetTriple(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 141: -#line 1684 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1684 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 142: -#line 1688 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1688 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary(yyvsp[0].StrVal); free(yyvsp[0].StrVal); ; break;} case 143: -#line 1692 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1692 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { ; break;} case 147: -#line 1701 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1701 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.StrVal = 0; ; break;} case 148: -#line 1703 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1703 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (*yyvsp[-1].TypeVal == Type::VoidTy) ThrowException("void typed arguments are invalid!"); @@ -3118,7 +3118,7 @@ ; break;} case 149: -#line 1709 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1709 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = yyvsp[-2].ArgList; yyvsp[-2].ArgList->push_back(*yyvsp[0].ArgVal); @@ -3126,7 +3126,7 @@ ; break;} case 150: -#line 1714 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1714 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = new std::vector >(); yyval.ArgList->push_back(*yyvsp[0].ArgVal); @@ -3134,13 +3134,13 @@ ; break;} case 151: -#line 1720 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1720 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = yyvsp[0].ArgList; ; break;} case 152: -#line 1723 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1723 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = yyvsp[-2].ArgList; yyval.ArgList->push_back(std::pair >(); yyval.ArgList->push_back(std::make_pair(new PATypeHolder(Type::VoidTy), (char*)0)); ; break;} case 154: -#line 1732 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1732 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ArgList = 0; ; break;} case 155: -#line 1737 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1737 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { UnEscapeLexed(yyvsp[-5].StrVal); std::string FunctionName(yyvsp[-5].StrVal); @@ -3248,7 +3248,7 @@ ; break;} case 158: -#line 1824 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1824 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = CurFun.CurrentFunction; @@ -3258,84 +3258,84 @@ ; break;} case 161: -#line 1834 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1834 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = yyvsp[-1].FunctionVal; ; break;} case 162: -#line 1838 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1838 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = true; ; break;} case 163: -#line 1838 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1838 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = CurFun.CurrentFunction; CurFun.FunctionDone(); ; break;} case 164: -#line 1847 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1847 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 165: -#line 1850 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1850 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 166: -#line 1854 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1854 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // A reference to a direct constant yyval.ValIDVal = ValID::create(yyvsp[0].SInt64Val); ; break;} case 167: -#line 1857 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1857 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(yyvsp[0].UInt64Val); ; break;} case 168: -#line 1860 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1860 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Perhaps it's an FP constant? yyval.ValIDVal = ValID::create(yyvsp[0].FPVal); ; break;} case 169: -#line 1863 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1863 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(ConstantBool::True); ; break;} case 170: -#line 1866 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1866 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(ConstantBool::False); ; break;} case 171: -#line 1869 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1869 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::createNull(); ; break;} case 172: -#line 1872 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1872 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::createUndef(); ; break;} case 173: -#line 1875 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1875 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // A vector zero constant. yyval.ValIDVal = ValID::createZeroInit(); ; break;} case 174: -#line 1878 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1878 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized packed vector const Type *ETy = (*yyvsp[-1].ConstVector)[0]->getType(); int NumElements = yyvsp[-1].ConstVector->size(); @@ -3362,13 +3362,13 @@ ; break;} case 175: -#line 1902 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1902 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValIDVal = ValID::create(yyvsp[0].ConstVal); ; break;} case 176: -#line 1905 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1905 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { char *End = UnEscapeLexed(yyvsp[-2].StrVal, true); std::string AsmStr = std::string(yyvsp[-2].StrVal, End); @@ -3380,37 +3380,37 @@ ; break;} case 177: -#line 1918 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1918 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Is it an integer reference...? yyval.ValIDVal = ValID::create(yyvsp[0].SIntVal); ; break;} case 178: -#line 1921 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1921 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? yyval.ValIDVal = ValID::create(yyvsp[0].StrVal); ; break;} case 181: -#line 1932 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1932 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueVal = getVal(*yyvsp[-1].TypeVal, yyvsp[0].ValIDVal); delete yyvsp[-1].TypeVal; ; break;} case 182: -#line 1936 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1936 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.FunctionVal = yyvsp[-1].FunctionVal; ; break;} case 183: -#line 1939 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1939 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Do not allow functions with 0 basic blocks yyval.FunctionVal = yyvsp[-1].FunctionVal; ; break;} case 184: -#line 1947 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1947 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { setValueName(yyvsp[0].TermInstVal, yyvsp[-1].StrVal); InsertValue(yyvsp[0].TermInstVal); @@ -3421,14 +3421,14 @@ ; break;} case 185: -#line 1956 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1956 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyvsp[-1].BasicBlockVal->getInstList().push_back(yyvsp[0].InstVal); yyval.BasicBlockVal = yyvsp[-1].BasicBlockVal; ; break;} case 186: -#line 1960 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1960 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BasicBlockVal = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); @@ -3441,7 +3441,7 @@ ; break;} case 187: -#line 1970 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1970 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BasicBlockVal = CurBB = getBBVal(ValID::create(yyvsp[0].StrVal), true); @@ -3454,31 +3454,31 @@ ; break;} case 188: -#line 1981 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1981 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Return with a result... yyval.TermInstVal = new ReturnInst(yyvsp[0].ValueVal); ; break;} case 189: -#line 1984 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1984 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Return with no result... yyval.TermInstVal = new ReturnInst(); ; break;} case 190: -#line 1987 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1987 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Unconditional Branch... yyval.TermInstVal = new BranchInst(getBBVal(yyvsp[0].ValIDVal)); ; break;} case 191: -#line 1990 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1990 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TermInstVal = new BranchInst(getBBVal(yyvsp[-3].ValIDVal), getBBVal(yyvsp[0].ValIDVal), getVal(Type::BoolTy, yyvsp[-6].ValIDVal)); ; break;} case 192: -#line 1993 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 1993 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { SwitchInst *S = new SwitchInst(getVal(yyvsp[-7].PrimType, yyvsp[-6].ValIDVal), getBBVal(yyvsp[-3].ValIDVal), yyvsp[-1].JumpTable->size()); yyval.TermInstVal = S; @@ -3495,14 +3495,14 @@ ; break;} case 193: -#line 2007 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2007 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { SwitchInst *S = new SwitchInst(getVal(yyvsp[-6].PrimType, yyvsp[-5].ValIDVal), getBBVal(yyvsp[-2].ValIDVal), 0); yyval.TermInstVal = S; ; break;} case 194: -#line 2012 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2012 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PFTy; const FunctionType *Ty; @@ -3557,19 +3557,19 @@ ; break;} case 195: -#line 2064 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2064 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TermInstVal = new UnwindInst(); ; break;} case 196: -#line 2067 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2067 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.TermInstVal = new UnreachableInst(); ; break;} case 197: -#line 2073 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2073 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.JumpTable = yyvsp[-5].JumpTable; Constant *V = cast(getValNonImprovising(yyvsp[-4].PrimType, yyvsp[-3].ValIDVal)); @@ -3580,7 +3580,7 @@ ; break;} case 198: -#line 2081 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2081 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.JumpTable = new std::vector >(); Constant *V = cast(getValNonImprovising(yyvsp[-4].PrimType, yyvsp[-3].ValIDVal)); @@ -3592,7 +3592,7 @@ ; break;} case 199: -#line 2091 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2091 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Is this definition named?? if so, assign the name... setValueName(yyvsp[0].InstVal, yyvsp[-1].StrVal); @@ -3601,7 +3601,7 @@ ; break;} case 200: -#line 2098 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2098 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Used for PHI nodes yyval.PHIList = new std::list >(); yyval.PHIList->push_back(std::make_pair(getVal(*yyvsp[-5].TypeVal, yyvsp[-3].ValIDVal), getBBVal(yyvsp[-1].ValIDVal))); @@ -3609,7 +3609,7 @@ ; break;} case 201: -#line 2103 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2103 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.PHIList = yyvsp[-6].PHIList; yyvsp[-6].PHIList->push_back(std::make_pair(getVal(yyvsp[-6].PHIList->front().first->getType(), yyvsp[-3].ValIDVal), @@ -3617,37 +3617,37 @@ ; break;} case 202: -#line 2110 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2110 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { // Used for call statements, and memory insts... yyval.ValueList = new std::vector(); yyval.ValueList->push_back(yyvsp[0].ValueVal); ; break;} case 203: -#line 2114 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2114 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = yyvsp[-2].ValueList; yyvsp[-2].ValueList->push_back(yyvsp[0].ValueVal); ; break;} case 205: -#line 2120 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2120 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = 0; ; break;} case 206: -#line 2122 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2122 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 207: -#line 2125 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2125 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 208: -#line 2131 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2131 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!(*yyvsp[-3].TypeVal)->isInteger() && !(*yyvsp[-3].TypeVal)->isFloatingPoint() && !isa((*yyvsp[-3].TypeVal).get())) @@ -3662,7 +3662,7 @@ ; break;} case 209: -#line 2143 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2143 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!(*yyvsp[-3].TypeVal)->isIntegral()) { if (!isa(yyvsp[-3].TypeVal->get()) || @@ -3676,7 +3676,7 @@ ; break;} case 210: -#line 2154 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2154 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if(isa((*yyvsp[-3].TypeVal).get())) { ThrowException( @@ -3689,7 +3689,7 @@ ; break;} case 211: -#line 2164 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2164 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { std::cerr << "WARNING: Use of eliminated 'not' instruction:" << " Replacing with 'xor'.\n"; @@ -3704,7 +3704,7 @@ ; break;} case 212: -#line 2176 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2176 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[0].ValueVal->getType() != Type::UByteTy) ThrowException("Shift amount must be ubyte!"); @@ -3714,7 +3714,7 @@ ; break;} case 213: -#line 2183 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2183 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!yyvsp[0].TypeVal->get()->isFirstClassType()) ThrowException("cast instruction to a non-primitive type: '" + @@ -3724,7 +3724,7 @@ ; break;} case 214: -#line 2190 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2190 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (yyvsp[-4].ValueVal->getType() != Type::BoolTy) ThrowException("select condition must be boolean!"); @@ -3734,7 +3734,7 @@ ; break;} case 215: -#line 2197 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2197 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { NewVarArgs = true; yyval.InstVal = new VAArgInst(yyvsp[-2].ValueVal, *yyvsp[0].TypeVal); @@ -3742,7 +3742,7 @@ ; break;} case 216: -#line 2202 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2202 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { ObsoleteVarArgs = true; const Type* ArgTy = yyvsp[-2].ValueVal->getType(); @@ -3764,7 +3764,7 @@ ; break;} case 217: -#line 2221 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2221 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { ObsoleteVarArgs = true; const Type* ArgTy = yyvsp[-2].ValueVal->getType(); @@ -3789,7 +3789,7 @@ ; break;} case 218: -#line 2243 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2243 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-2].ValueVal->getType())) ThrowException("First operand of extractelement must be " @@ -3800,7 +3800,7 @@ ; break;} case 219: -#line 2251 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2251 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-4].ValueVal->getType())) ThrowException("First operand of insertelement must be " @@ -3815,7 +3815,7 @@ ; break;} case 220: -#line 2263 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2263 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = yyvsp[0].PHIList->front().first->getType(); if (!Ty->isFirstClassType()) @@ -3832,7 +3832,7 @@ ; break;} case 221: -#line 2277 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2277 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PFTy; const FunctionType *Ty; @@ -3892,65 +3892,65 @@ ; break;} case 222: -#line 2334 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2334 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = yyvsp[0].InstVal; ; break;} case 223: -#line 2340 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2340 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = yyvsp[0].ValueList; ; break;} case 224: -#line 2342 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2342 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.ValueList = new std::vector(); ; break;} case 225: -#line 2346 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2346 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = true; ; break;} case 226: -#line 2349 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2349 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.BoolVal = false; ; break;} case 227: -#line 2355 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2355 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new MallocInst(*yyvsp[-1].TypeVal, 0, yyvsp[0].UIntVal); delete yyvsp[-1].TypeVal; ; break;} case 228: -#line 2359 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2359 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new MallocInst(*yyvsp[-4].TypeVal, getVal(yyvsp[-2].PrimType, yyvsp[-1].ValIDVal), yyvsp[0].UIntVal); delete yyvsp[-4].TypeVal; ; break;} case 229: -#line 2363 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2363 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new AllocaInst(*yyvsp[-1].TypeVal, 0, yyvsp[0].UIntVal); delete yyvsp[-1].TypeVal; ; break;} case 230: -#line 2367 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2367 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { yyval.InstVal = new AllocaInst(*yyvsp[-4].TypeVal, getVal(yyvsp[-2].PrimType, yyvsp[-1].ValIDVal), yyvsp[0].UIntVal); delete yyvsp[-4].TypeVal; ; break;} case 231: -#line 2371 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2371 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[0].ValueVal->getType())) ThrowException("Trying to free nonpointer type " + @@ -3959,7 +3959,7 @@ ; break;} case 232: -#line 2378 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2378 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-1].TypeVal->get())) ThrowException("Can't load from nonpointer type: " + @@ -3972,7 +3972,7 @@ ; break;} case 233: -#line 2388 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2388 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { const PointerType *PT = dyn_cast(yyvsp[-1].TypeVal->get()); if (!PT) @@ -3988,7 +3988,7 @@ ; break;} case 234: -#line 2401 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2401 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" { if (!isa(yyvsp[-2].TypeVal->get())) ThrowException("getelementptr insn requires pointer operand!"); @@ -4233,7 +4233,7 @@ } return 1; } -#line 2424 "/Users/sabre/cvs/llvm/lib/AsmParser/llvmAsmParser.y" +#line 2424 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y" int yyerror(const char *ErrorMsg) { std::string where Index: llvm/lib/AsmParser/llvmAsmParser.y.cvs diff -u llvm/lib/AsmParser/llvmAsmParser.y.cvs:1.1 llvm/lib/AsmParser/llvmAsmParser.y.cvs:1.2 --- llvm/lib/AsmParser/llvmAsmParser.y.cvs:1.1 Wed Feb 15 01:22:58 2006 +++ llvm/lib/AsmParser/llvmAsmParser.y.cvs Sat Mar 4 01:53:41 2006 @@ -108,8 +108,8 @@ // Look for intrinsic functions and CallInst that need to be upgraded for (Module::iterator FI = CurrentModule->begin(),FE = CurrentModule->end(); - FI != FE; ++FI) - UpgradeCallsToIntrinsic(FI); + FI != FE; ) + UpgradeCallsToIntrinsic(FI++); Values.clear(); // Clear out function local definitions Types.clear(); From lattner at cs.uiuc.edu Sat Mar 4 02:45:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 02:45:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200603040845.CAA11631@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.10 -> 1.11 --- Log message: Add a note --- Diffs of the changes: (+17 -0) README.txt | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.10 llvm/lib/Target/README.txt:1.11 --- llvm/lib/Target/README.txt:1.10 Fri Mar 3 19:19:34 2006 +++ llvm/lib/Target/README.txt Sat Mar 4 02:44:51 2006 @@ -101,3 +101,20 @@ This would be a win on ppc32, but not x86 or ppc64. +//===---------------------------------------------------------------------===// + +Pull add through mul/shift to handle this: + +int foo(int P[4][4], int i) { + return P[i+2][1]; +} + +better than this (no addi needed): + +_foo: + addi r2, r4, 2 + slwi r2, r2, 4 + add r2, r3, r2 + lwz r3, 4(r2) + blr + From lattner at cs.uiuc.edu Sat Mar 4 03:30:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 03:30:20 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Reassociate/mulfactor.ll Message-ID: <200603040930.DAA01714@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Reassociate: mulfactor.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+14 -0) mulfactor.ll | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/test/Regression/Transforms/Reassociate/mulfactor.ll diff -c /dev/null llvm/test/Regression/Transforms/Reassociate/mulfactor.ll:1.1 *** /dev/null Sat Mar 4 03:30:18 2006 --- llvm/test/Regression/Transforms/Reassociate/mulfactor.ll Sat Mar 4 03:30:08 2006 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | opt -reassociate -instcombine | llvm-dis | grep mul | wc -l | grep 2 + + ; This should have exactly 2 multiplies when we're done. + + int %f(int %a, int %b) { + %tmp.2 = mul int %a, %a + %tmp.5 = shl int %a, ubyte 1 + %tmp.6 = mul int %tmp.5, %b + %tmp.10 = mul int %b, %b + %tmp.7 = add int %tmp.6, %tmp.2 + %tmp.11 = add int %tmp.7, %tmp.10 + ret int %tmp.11 + } + From lattner at cs.uiuc.edu Sat Mar 4 03:31:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 03:31:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/Reassociate.cpp Message-ID: <200603040931.DAA01838@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: Reassociate.cpp updated: 1.56 -> 1.57 --- Log message: Add factoring of multiplications, e.g. turning A*A+A*B into A*(A+B). Testcase here: Transforms/Reassociate/mulfactor.ll --- Diffs of the changes: (+186 -49) Reassociate.cpp | 235 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 186 insertions(+), 49 deletions(-) Index: llvm/lib/Transforms/Scalar/Reassociate.cpp diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.56 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.57 --- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.56 Sun Jan 22 17:32:06 2006 +++ llvm/lib/Transforms/Scalar/Reassociate.cpp Sat Mar 4 03:31:13 2006 @@ -41,6 +41,7 @@ Statistic<> NumChanged("reassociate","Number of insts reassociated"); Statistic<> NumSwapped("reassociate","Number of insts with operands swapped"); Statistic<> NumAnnihil("reassociate","Number of expr tree annihilated"); + Statistic<> NumFactor ("reassociate","Number of multiplies factored"); struct ValueEntry { unsigned Rank; @@ -50,7 +51,20 @@ inline bool operator<(const ValueEntry &LHS, const ValueEntry &RHS) { return LHS.Rank > RHS.Rank; // Sort so that highest rank goes to start. } +} +/// PrintOps - Print out the expression identified in the Ops list. +/// +static void PrintOps(Instruction *I, const std::vector &Ops) { + Module *M = I->getParent()->getParent()->getParent(); + std::cerr << Instruction::getOpcodeName(I->getOpcode()) << " " + << *Ops[0].Op->getType(); + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + WriteAsOperand(std::cerr << " ", Ops[i].Op, false, true, M) + << "," << Ops[i].Rank; +} + +namespace { class Reassociate : public FunctionPass { std::map RankMap; std::map ValueRankMap; @@ -66,10 +80,13 @@ unsigned getRank(Value *V); void RewriteExprTree(BinaryOperator *I, unsigned Idx, std::vector &Ops); - void OptimizeExpression(unsigned Opcode, std::vector &Ops); + Value *OptimizeExpression(BinaryOperator *I, std::vector &Ops); void LinearizeExprTree(BinaryOperator *I, std::vector &Ops); void LinearizeExpr(BinaryOperator *I); + Value *RemoveFactorFromExpression(Value *V, Value *Factor); void ReassociateBB(BasicBlock *BB); + + void RemoveDeadBinaryOp(Value *V); }; RegisterOpt X("reassociate", "Reassociate expressions"); @@ -78,6 +95,15 @@ // Public interface to the Reassociate pass FunctionPass *llvm::createReassociatePass() { return new Reassociate(); } +void Reassociate::RemoveDeadBinaryOp(Value *V) { + BinaryOperator *BOp = dyn_cast(V); + if (!BOp || !BOp->use_empty()) return; + + Value *LHS = BOp->getOperand(0), *RHS = BOp->getOperand(1); + RemoveDeadBinaryOp(LHS); + RemoveDeadBinaryOp(RHS); +} + static bool isUnmovableInstruction(Instruction *I) { if (I->getOpcode() == Instruction::PHI || @@ -207,9 +233,6 @@ /// form of the the expression (((a+b)+c)+d), and collects information about the /// rank of the non-tree operands. /// -/// This returns the rank of the RHS operand, which is known to be the highest -/// rank value in the expression tree. -/// void Reassociate::LinearizeExprTree(BinaryOperator *I, std::vector &Ops) { Value *LHS = I->getOperand(0), *RHS = I->getOperand(1); @@ -279,12 +302,17 @@ if (i+2 == Ops.size()) { if (I->getOperand(0) != Ops[i].Op || I->getOperand(1) != Ops[i+1].Op) { + Value *OldLHS = I->getOperand(0); DEBUG(std::cerr << "RA: " << *I); I->setOperand(0, Ops[i].Op); I->setOperand(1, Ops[i+1].Op); DEBUG(std::cerr << "TO: " << *I); MadeChange = true; ++NumChanged; + + // If we reassociated a tree to fewer operands (e.g. (1+a+2) -> (a+3) + // delete the extra, now dead, nodes. + RemoveDeadBinaryOp(OldLHS); } return; } @@ -297,7 +325,15 @@ MadeChange = true; ++NumChanged; } - RewriteExprTree(cast(I->getOperand(0)), i+1, Ops); + + BinaryOperator *LHS = cast(I->getOperand(0)); + assert(LHS->getOpcode() == I->getOpcode() && + "Improper expression tree!"); + + // Compactify the tree instructions together with each other to guarantee + // that the expression tree is dominated by all of Ops. + LHS->moveBefore(I); + RewriteExprTree(LHS, i+1, Ops); } @@ -405,19 +441,57 @@ return i; } -void Reassociate::OptimizeExpression(unsigned Opcode, - std::vector &Ops) { +/// EmitAddTreeOfValues - Emit a tree of add instructions, summing Ops together +/// and returning the result. Insert the tree before I. +static Value *EmitAddTreeOfValues(Instruction *I, std::vector &Ops) { + if (Ops.size() == 1) return Ops.back(); + + Value *V1 = Ops.back(); + Ops.pop_back(); + Value *V2 = EmitAddTreeOfValues(I, Ops); + return BinaryOperator::createAdd(V2, V1, "tmp", I); +} + +/// RemoveFactorFromExpression - If V is an expression tree that is a +/// multiplication sequence, and if this sequence contains a multiply by Factor, +/// remove Factor from the tree and return the new tree. +Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) { + BinaryOperator *BO = isReassociableOp(V, Instruction::Mul); + if (!BO) return 0; + + std::vector Factors; + LinearizeExprTree(BO, Factors); + + bool FoundFactor = false; + for (unsigned i = 0, e = Factors.size(); i != e; ++i) + if (Factors[i].Op == Factor) { + FoundFactor = true; + Factors.erase(Factors.begin()+i); + break; + } + if (!FoundFactor) return 0; + + if (Factors.size() == 1) return Factors[0].Op; + + RewriteExprTree(BO, 0, Factors); + return BO; +} + + +Value *Reassociate::OptimizeExpression(BinaryOperator *I, + std::vector &Ops) { // Now that we have the linearized expression tree, try to optimize it. // Start by folding any constants that we found. bool IterateOptimization = false; - if (Ops.size() == 1) return; + if (Ops.size() == 1) return Ops[0].Op; + unsigned Opcode = I->getOpcode(); + if (Constant *V1 = dyn_cast(Ops[Ops.size()-2].Op)) if (Constant *V2 = dyn_cast(Ops.back().Op)) { Ops.pop_back(); Ops.back().Op = ConstantExpr::get(Opcode, V1, V2); - OptimizeExpression(Opcode, Ops); - return; + return OptimizeExpression(I, Ops); } // Check for destructive annihilation due to a constant being used. @@ -426,30 +500,24 @@ default: break; case Instruction::And: if (CstVal->isNullValue()) { // ... & 0 -> 0 - Ops[0].Op = CstVal; - Ops.erase(Ops.begin()+1, Ops.end()); ++NumAnnihil; - return; + return CstVal; } else if (CstVal->isAllOnesValue()) { // ... & -1 -> ... Ops.pop_back(); } break; case Instruction::Mul: if (CstVal->isNullValue()) { // ... * 0 -> 0 - Ops[0].Op = CstVal; - Ops.erase(Ops.begin()+1, Ops.end()); ++NumAnnihil; - return; + return CstVal; } else if (cast(CstVal)->getRawValue() == 1) { Ops.pop_back(); // ... * 1 -> ... } break; case Instruction::Or: if (CstVal->isAllOnesValue()) { // ... | -1 -> -1 - Ops[0].Op = CstVal; - Ops.erase(Ops.begin()+1, Ops.end()); ++NumAnnihil; - return; + return CstVal; } // FALLTHROUGH! case Instruction::Add: @@ -458,7 +526,7 @@ Ops.pop_back(); break; } - if (Ops.size() == 1) return; + if (Ops.size() == 1) return Ops[0].Op; // Handle destructive annihilation do to identities between elements in the // argument list here. @@ -477,15 +545,11 @@ unsigned FoundX = FindInOperandList(Ops, i, X); if (FoundX != i) { if (Opcode == Instruction::And) { // ...&X&~X = 0 - Ops[0].Op = Constant::getNullValue(X->getType()); - Ops.erase(Ops.begin()+1, Ops.end()); ++NumAnnihil; - return; + return Constant::getNullValue(X->getType()); } else if (Opcode == Instruction::Or) { // ...|X|~X = -1 - Ops[0].Op = ConstantIntegral::getAllOnesValue(X->getType()); - Ops.erase(Ops.begin()+1, Ops.end()); ++NumAnnihil; - return; + return ConstantIntegral::getAllOnesValue(X->getType()); } } } @@ -503,10 +567,8 @@ } else { assert(Opcode == Instruction::Xor); if (e == 2) { - Ops[0].Op = Constant::getNullValue(Ops[0].Op->getType()); - Ops.erase(Ops.begin()+1, Ops.end()); ++NumAnnihil; - return; + return Constant::getNullValue(Ops[0].Op->getType()); } // ... X^X -> ... Ops.erase(Ops.begin()+i, Ops.begin()+i+2); @@ -520,7 +582,7 @@ case Instruction::Add: // Scan the operand lists looking for X and -X pairs. If we find any, we - // can simplify the expression. X+-X == 0 + // can simplify the expression. X+-X == 0. for (unsigned i = 0, e = Ops.size(); i != e; ++i) { assert(i < Ops.size()); // Check for X and -X in the operand list. @@ -530,10 +592,8 @@ if (FoundX != i) { // Remove X and -X from the operand list. if (Ops.size() == 2) { - Ops[0].Op = Constant::getNullValue(X->getType()); - Ops.pop_back(); ++NumAnnihil; - return; + return Constant::getNullValue(X->getType()); } else { Ops.erase(Ops.begin()+i); if (i < FoundX) @@ -549,30 +609,99 @@ } } } + + + // Scan the operand list, checking to see if there are any common factors + // between operands. Consider something like A*A+A*B*C+D. We would like to + // reassociate this to A*(A+B*C)+D, which reduces the number of multiplies. + // To efficiently find this, we count the number of times a factor occurs + // for any ADD operands that are MULs. + std::map FactorOccurrences; + unsigned MaxOcc = 0; + Value *MaxOccVal = 0; + if (!I->getType()->isFloatingPoint()) { + for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + if (BinaryOperator *BOp = dyn_cast(Ops[i].Op)) + if (BOp->getOpcode() == Instruction::Mul && BOp->hasOneUse()) { + // Compute all of the factors of this added value. + std::vector Factors; + LinearizeExprTree(BOp, Factors); + assert(Factors.size() > 1 && "Bad linearize!"); + + // Add one to FactorOccurrences for each unique factor in this op. + if (Factors.size() == 2) { + unsigned Occ = ++FactorOccurrences[Factors[0].Op]; + if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factors[0].Op; } + if (Factors[0].Op != Factors[1].Op) { // Don't double count A*A. + Occ = ++FactorOccurrences[Factors[1].Op]; + if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factors[1].Op; } + } + } else { + std::set Duplicates; + for (unsigned i = 0, e = Factors.size(); i != e; ++i) + if (Duplicates.insert(Factors[i].Op).second) { + unsigned Occ = ++FactorOccurrences[Factors[i].Op]; + if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factors[i].Op; } + } + } + } + } + } + + // If any factor occurred more than one time, we can pull it out. + if (MaxOcc > 1) { + DEBUG(std::cerr << "\nFACTORING [" << MaxOcc << "]: " + << *MaxOccVal << "\n"); + + // Create a new instruction that uses the MaxOccVal twice. If we don't do + // this, we could otherwise run into situations where removing a factor + // from an expression will drop a use of maxocc, and this can cause + // RemoveFactorFromExpression on successive values to behave differently. + Instruction *DummyInst = BinaryOperator::createAdd(MaxOccVal, MaxOccVal); + std::vector NewMulOps; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + if (Value *V = RemoveFactorFromExpression(Ops[i].Op, MaxOccVal)) { + NewMulOps.push_back(V); + Ops.erase(Ops.begin()+i); + --i; --e; + } + } + + // No need for extra uses anymore. + delete DummyInst; + + Value *V = EmitAddTreeOfValues(I, NewMulOps); + // FIXME: Must optimize V now, to handle this case: + // A*A*B + A*A*C -> A*(A*B+A*C) -> A*(A*(B+C)) + V = BinaryOperator::createMul(V, MaxOccVal, "tmp", I); + + ++NumFactor; + + if (Ops.size() == 0) + return V; + + // Add the new value to the list of things being added. + Ops.insert(Ops.begin(), ValueEntry(getRank(V), V)); + + // Rewrite the tree so that there is now a use of V. + RewriteExprTree(I, 0, Ops); + return OptimizeExpression(I, Ops); + } break; //case Instruction::Mul: } if (IterateOptimization) - OptimizeExpression(Opcode, Ops); + return OptimizeExpression(I, Ops); + return 0; } -/// PrintOps - Print out the expression identified in the Ops list. -/// -static void PrintOps(unsigned Opcode, const std::vector &Ops, - BasicBlock *BB) { - Module *M = BB->getParent()->getParent(); - std::cerr << Instruction::getOpcodeName(Opcode) << " " - << *Ops[0].Op->getType(); - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - WriteAsOperand(std::cerr << " ", Ops[i].Op, false, true, M) - << "," << Ops[i].Rank; -} /// ReassociateBB - Inspect all of the instructions in this basic block, /// reassociating them as we go. void Reassociate::ReassociateBB(BasicBlock *BB) { - for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) { + for (BasicBlock::iterator BBI = BB->begin(); BBI != BB->end(); ) { + Instruction *BI = BBI++; if (BI->getOpcode() == Instruction::Shl && isa(BI->getOperand(1))) if (Instruction *NI = ConvertShiftToMul(BI)) { @@ -623,7 +752,7 @@ std::vector Ops; LinearizeExprTree(I, Ops); - DEBUG(std::cerr << "RAIn:\t"; PrintOps(I->getOpcode(), Ops, BB); + DEBUG(std::cerr << "RAIn:\t"; PrintOps(I, Ops); std::cerr << "\n"); // Now that we have linearized the tree to a list and have gathered all of @@ -636,7 +765,14 @@ // OptimizeExpression - Now that we have the expression tree in a convenient // sorted form, optimize it globally if possible. - OptimizeExpression(I->getOpcode(), Ops); + if (Value *V = OptimizeExpression(I, Ops)) { + // This expression tree simplified to something that isn't a tree, + // eliminate it. + DEBUG(std::cerr << "Reassoc to scalar: " << *V << "\n"); + I->replaceAllUsesWith(V); + RemoveDeadBinaryOp(I); + continue; + } // We want to sink immediates as deeply as possible except in the case where // this is a multiply tree used only by an add, and the immediate is a -1. @@ -650,13 +786,14 @@ Ops.pop_back(); } - DEBUG(std::cerr << "RAOut:\t"; PrintOps(I->getOpcode(), Ops, BB); + DEBUG(std::cerr << "RAOut:\t"; PrintOps(I, Ops); std::cerr << "\n"); if (Ops.size() == 1) { // This expression tree simplified to something that isn't a tree, // eliminate it. I->replaceAllUsesWith(Ops[0].Op); + RemoveDeadBinaryOp(I); } else { // Now that we ordered and optimized the expressions, splat them back into // the expression tree, removing any unneeded nodes. From lattner at cs.uiuc.edu Sat Mar 4 03:35:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 03:35:13 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Reassociate/mulfactor2.ll Message-ID: <200603040935.DAA02340@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Reassociate: mulfactor2.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+13 -0) mulfactor2.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/Regression/Transforms/Reassociate/mulfactor2.ll diff -c /dev/null llvm/test/Regression/Transforms/Reassociate/mulfactor2.ll:1.1 *** /dev/null Sat Mar 4 03:35:12 2006 --- llvm/test/Regression/Transforms/Reassociate/mulfactor2.ll Sat Mar 4 03:35:02 2006 *************** *** 0 **** --- 1,13 ---- + ; This should turn into one multiply and one add. + + ; RUN: llvm-as < mulfactor2.ll | opt -instcombine -reassociate -instcombine | llvm-dis | grep mul | wc -l | grep 1 && + ; RUN: llvm-as < mulfactor2.ll | opt -instcombine -reassociate -instcombine | llvm-dis | grep add | wc -l | grep 1 + int %main(int %t) { + %tmp.3 = mul int %t, 12 ; [#uses=1] + %tmp.4 = add int %tmp.3, 5 ; [#uses=1] + %tmp.6 = mul int %t, 6 ; [#uses=1] + %tmp.8 = mul int %tmp.4, 3 ; [#uses=1] + %tmp.9 = add int %tmp.8, %tmp.6 ; [#uses=1] + ret int %tmp.9 + } + From alenhar2 at cs.uiuc.edu Sat Mar 4 14:41:05 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sat, 4 Mar 2006 14:41:05 -0600 Subject: [llvm-commits] CVS: llvm-poolalloc/Regressions/2006-03-04.undefArg.ll Message-ID: <200603042041.OAA16451@zion.cs.uiuc.edu> Changes in directory llvm-poolalloc/Regressions: 2006-03-04.undefArg.ll added (r1.1) --- Log message: in PC, the argument of count is an undefined value and has some cloning problem (perhaps) --- Diffs of the changes: (+96 -0) 2006-03-04.undefArg.ll | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 96 insertions(+) Index: llvm-poolalloc/Regressions/2006-03-04.undefArg.ll diff -c /dev/null llvm-poolalloc/Regressions/2006-03-04.undefArg.ll:1.1 *** /dev/null Sat Mar 4 14:41:04 2006 --- llvm-poolalloc/Regressions/2006-03-04.undefArg.ll Sat Mar 4 14:40:54 2006 *************** *** 0 **** --- 1,96 ---- + ; ModuleID = 'bugpoint-reduced-simplified.bc' + target endian = little + target pointersize = 64 + target triple = "alphaev6-unknown-linux-gnu" + deplibs = [ "c", "crtend" ] + %struct..TorRec = type { int, void ()* } + %struct.CON_list_struct = type { %struct.CON_list_struct*, %struct.CON_node_struct* } + %struct.CON_node_struct = type { %struct.DIS_list_struct*, %struct.DIS_list_struct*, int } + %struct.Connector_struct = type { short, short, sbyte, sbyte, %struct.Connector_struct*, sbyte* } + %struct.DIS_list_struct = type { %struct.DIS_list_struct*, %struct.DIS_node_struct* } + %struct.DIS_node_struct = type { %struct.CON_list_struct*, %struct.List_o_links_struct*, int } + %struct.D_type_list_struct = type { %struct.D_type_list_struct*, int } + %struct.Dict_node_struct = type { sbyte*, %struct.Word_file_struct*, %struct.Exp_struct*, %struct.Dict_node_struct*, %struct.Dict_node_struct* } + %struct.Disjunct_struct = type { %struct.Disjunct_struct*, short, sbyte, sbyte*, %struct.Connector_struct*, %struct.Connector_struct* } + %struct.E_list_struct = type { %struct.E_list_struct*, %struct.Exp_struct* } + %struct.Exp_struct = type { sbyte, ubyte, sbyte, sbyte, { sbyte* } } + %struct.Image_node_struct = type { %struct.Image_node_struct*, %struct.Connector_struct*, int } + %struct.Link_struct = type { int, int, %struct.Connector_struct*, %struct.Connector_struct*, sbyte* } + %struct.Linkage_info_struct = type { int, short, short, short, short, short } + %struct.Links_to_patch_struct = type { %struct.Links_to_patch_struct*, int, sbyte, int } + %struct.List_o_links_struct = type { int, int, int, %struct.List_o_links_struct* } + %struct.Match_node_struct = type { %struct.Match_node_struct*, %struct.Disjunct_struct* } + %struct.PP_node_struct = type { %struct.D_type_list_struct**, %struct.Violation_list_struct* } + %struct.Table_connector = type { short, short, %struct.Connector_struct*, %struct.Connector_struct*, short, int, %struct.Table_connector* } + %struct.Tconnector_struct = type { sbyte, sbyte, %struct.Tconnector_struct*, sbyte* } + %struct.TorRec = type { int, void ()* } + %struct.Violation_list_struct = type { %struct.Violation_list_struct*, sbyte* } + %struct.Word_file_struct = type { [60 x sbyte], int, %struct.Word_file_struct* } + %struct.Word_struct = type { [60 x sbyte], %struct.X_node_struct*, %struct.Disjunct_struct* } + %struct.X_node_struct = type { sbyte*, %struct.Exp_struct*, %struct.X_node_struct* } + %struct._IO_FILE = type { int, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, %struct._IO_marker*, %struct._IO_FILE*, int, int, long, ushort, sbyte, [1 x sbyte], sbyte*, long, sbyte*, sbyte*, int, [44 x sbyte] } + %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, int } + %struct.__va_list_tag = type { sbyte*, int } + %struct.c_list_struct = type { %struct.Connector_struct*, int, %struct.c_list_struct* } + %struct.clause_struct = type { %struct.clause_struct*, int, int, %struct.Tconnector_struct* } + %struct.d_tree_leaf_struct = type { %struct.domain_struct*, int, %struct.d_tree_leaf_struct* } + %struct.domain_struct = type { sbyte*, int, %struct.List_o_links_struct*, int, int, %struct.d_tree_leaf_struct*, %struct.domain_struct* } + %struct.label_node_struct = type { int, %struct.label_node_struct* } + %struct.patch_element_struct = type { sbyte, sbyte, int, int } + %struct.string_node_struct = type { sbyte*, int, %struct.string_node_struct* } + %sentence = external global [250 x %struct.Word_struct] ; <[250 x %struct.Word_struct]*> [#uses=2] + %mn_free_list = external global %struct.Match_node_struct* ; <%struct.Match_node_struct**> [#uses=1] + + implementation ; Functions: + + declare fastcc %struct.Match_node_struct* %form_match_list(%struct.Connector_struct*) + + internal fastcc void %prune() { + entry: + %tmp.15 = getelementptr [250 x %struct.Word_struct]* %sentence, long 0, int 0, uint 2 ; <%struct.Disjunct_struct**> [#uses=1] + %tmp.16 = load %struct.Disjunct_struct** %tmp.15 ; <%struct.Disjunct_struct*> [#uses=1] + %tmp.44 = getelementptr %struct.Disjunct_struct* %tmp.16, long 0, uint 5 ; <%struct.Connector_struct**> [#uses=1] + %tmp.45 = load %struct.Connector_struct** %tmp.44 ; <%struct.Connector_struct*> [#uses=1] + free %struct.Connector_struct* %tmp.45 + ret void + } + + int %main(int %argc, sbyte** %argv) { + entry: + %tmp.2 = load %struct.Disjunct_struct** getelementptr ([250 x %struct.Word_struct]* %sentence, long 0, long 0, uint 2) ; <%struct.Disjunct_struct*> [#uses=1] + %tmp.16 = getelementptr %struct.Disjunct_struct* %tmp.2, long 0, uint 5 ; <%struct.Connector_struct**> [#uses=1] + %tmp.17 = load %struct.Connector_struct** %tmp.16 ; <%struct.Connector_struct*> [#uses=1] + %tmp.13 = tail call fastcc int %count( %struct.Connector_struct* %tmp.17 ) ; [#uses=0] + %tmp.24 = tail call fastcc int %count( %struct.Connector_struct* null ) ; [#uses=0] + ret int 0 + } + + internal fastcc int %count(%struct.Connector_struct* %le) { + no_exit.0: ; preds = %endif.4 + %tmp.101 = tail call fastcc %struct.Match_node_struct* %form_match_list( %struct.Connector_struct* %le) + br label %no_exit.1 + + no_exit.1: ; preds = %loopexit.2, %no_exit.0 + %m.2.0 = phi %struct.Match_node_struct* [ %tmp.101, %no_exit.0 ], [ %tmp.542, %loopexit.2 ] ; <%struct.Match_node_struct*> [#uses=2] + %tmp.112 = getelementptr %struct.Match_node_struct* %m.2.0, long 0, uint 1 ; <%struct.Disjunct_struct**> [#uses=1] + %tmp.113 = load %struct.Disjunct_struct** %tmp.112 ; <%struct.Disjunct_struct*> [#uses=1] + br bool false, label %loopexit.2, label %no_exit.2.preheader + + no_exit.2.preheader: ; preds = %no_exit.1 + %tmp.141 = getelementptr %struct.Disjunct_struct* %tmp.113, long 0, uint 5 ; <%struct.Connector_struct**> [#uses=1] + %tmp.432 = load %struct.Connector_struct** %tmp.141 ; <%struct.Connector_struct*> [#uses=1] + %tmp.427 = tail call fastcc int %count( %struct.Connector_struct* %tmp.432 ) ; [#uses=0] + ret int 0 + + loopexit.2: ; preds = %no_exit.1 + %tmp.541 = getelementptr %struct.Match_node_struct* %m.2.0, long 0, uint 0 ; <%struct.Match_node_struct**> [#uses=1] + %tmp.542 = load %struct.Match_node_struct** %tmp.541 ; <%struct.Match_node_struct*> [#uses=1] + br bool false, label %no_exit.i.preheader, label %no_exit.1 + + no_exit.i.preheader: ; preds = %loopexit.2 + %mn_free_list.promoted = load %struct.Match_node_struct** %mn_free_list ; <%struct.Match_node_struct*> [#uses=1] + %tmp.5.i = getelementptr %struct.Match_node_struct* %tmp.101, long 0, uint 0 ; <%struct.Match_node_struct**> [#uses=1] + store %struct.Match_node_struct* %mn_free_list.promoted, %struct.Match_node_struct** %tmp.5.i + ret int 0 + } + From lattner at cs.uiuc.edu Sat Mar 4 15:27:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 15:27:45 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Applications/obsequi/utils.c utils.h Message-ID: <200603042127.PAA17343@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Applications/obsequi: utils.c updated: 1.1 -> 1.2 utils.h updated: 1.3 -> 1.4 --- Log message: Portability fixes --- Diffs of the changes: (+2 -5) utils.c | 2 ++ utils.h | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) Index: llvm-test/MultiSource/Applications/obsequi/utils.c diff -u llvm-test/MultiSource/Applications/obsequi/utils.c:1.1 llvm-test/MultiSource/Applications/obsequi/utils.c:1.2 --- llvm-test/MultiSource/Applications/obsequi/utils.c:1.1 Tue May 11 14:34:13 2004 +++ llvm-test/MultiSource/Applications/obsequi/utils.c Sat Mar 4 15:27:33 2006 @@ -102,6 +102,7 @@ // This function stores the string created from FORMAT and the // following args to the end of the string STR. //======================================================== +#if 0 extern s32bit asprintf_my(char **str, s32bit offset, const char *format, ... ) { @@ -127,6 +128,7 @@ va_end (ap); return nchars; } +#endif //######################################################## Index: llvm-test/MultiSource/Applications/obsequi/utils.h diff -u llvm-test/MultiSource/Applications/obsequi/utils.h:1.3 llvm-test/MultiSource/Applications/obsequi/utils.h:1.4 --- llvm-test/MultiSource/Applications/obsequi/utils.h:1.3 Wed Jun 23 09:23:34 2004 +++ llvm-test/MultiSource/Applications/obsequi/utils.h Sat Mar 4 15:27:33 2006 @@ -7,13 +7,8 @@ #define _GNU_SOURCE //Need this so that __USE_GNU is defined #endif -#include - #include #include -#if !defined(__FreeBSD__) -# include -#endif #include From lattner at cs.uiuc.edu Sat Mar 4 15:48:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 15:48:03 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Applications/obsequi/Makefile obsequi.c Message-ID: <200603042148.PAA17676@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Applications/obsequi: Makefile updated: 1.3 -> 1.4 obsequi.c updated: 1.2 -> 1.3 --- Log message: more portability fixes, obsequi now works on darwin. --- Diffs of the changes: (+8 -3) Makefile | 4 ++-- obsequi.c | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) Index: llvm-test/MultiSource/Applications/obsequi/Makefile diff -u llvm-test/MultiSource/Applications/obsequi/Makefile:1.3 llvm-test/MultiSource/Applications/obsequi/Makefile:1.4 --- llvm-test/MultiSource/Applications/obsequi/Makefile:1.3 Sat Jan 15 21:16:10 2005 +++ llvm-test/MultiSource/Applications/obsequi/Makefile Sat Mar 4 15:47:51 2006 @@ -2,7 +2,7 @@ PROG = Obsequi CPPFLAGS += -DCOUNTBITS16 -DLASTBIT16 -DCOUNTMOVES_TABLE -DHASHCODEBITS=23 CPPFLAGS += -DTWO_STAGE_GENERATION -LDFLAGS = -lsupc++ -LIBS += -lsupc++ +LDFLAGS = -lsupc++ -lcurses +LIBS += -lsupc++ -lcurses STDIN_FILENAME=$(PROJ_SRC_DIR)/input include ../../Makefile.multisrc Index: llvm-test/MultiSource/Applications/obsequi/obsequi.c diff -u llvm-test/MultiSource/Applications/obsequi/obsequi.c:1.2 llvm-test/MultiSource/Applications/obsequi/obsequi.c:1.3 --- llvm-test/MultiSource/Applications/obsequi/obsequi.c:1.2 Tue May 11 15:11:16 2004 +++ llvm-test/MultiSource/Applications/obsequi/obsequi.c Sat Mar 4 15:47:51 2006 @@ -34,6 +34,12 @@ #include "cppflags.h" #include "interface.h" +// LLVM: define our own getline for portability +#define getline getline_llvm + +ssize_t getline(char **lineptr, size_t *n, FILE *stream) { + return getstr (lineptr, n, stream, '\n', 0, 0); +} //######################################################## // Function templates. @@ -172,7 +178,6 @@ char c1, c2; s32bit r, c; - while( (len = getline(&line, &line_size, stdin)) != -1){ s32bit t; From lattner at cs.uiuc.edu Sat Mar 4 15:48:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 15:48:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200603042148.PAA17683@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.77 -> 1.78 --- Log message: Fix a crash compiling Obsequi --- Diffs of the changes: (+12 -5) BasicAliasAnalysis.cpp | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.77 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.78 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.77 Fri Mar 3 20:06:34 2006 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Sat Mar 4 15:48:01 2006 @@ -637,17 +637,24 @@ // than the first constant index of GEP2. // Advance BasePtr[12]Ty over this first differing constant operand. - BasePtr2Ty = cast(BasePtr1Ty)->getTypeAtIndex(GEP2Ops[FirstConstantOper]); - BasePtr1Ty = cast(BasePtr1Ty)->getTypeAtIndex(GEP1Ops[FirstConstantOper]); + BasePtr2Ty = cast(BasePtr1Ty)-> + getTypeAtIndex(GEP2Ops[FirstConstantOper]); + BasePtr1Ty = cast(BasePtr1Ty)-> + getTypeAtIndex(GEP1Ops[FirstConstantOper]); // We are going to be using TargetData::getIndexedOffset to determine the // offset that each of the GEP's is reaching. To do this, we have to convert // all variable references to constant references. To do this, we convert the - // initial equal sequence of variables into constant zeros to start with. - for (unsigned i = 0; i != FirstConstantOper; ++i) - if (!isa(GEP1Ops[i]) || !isa(GEP2Ops[i])) + // initial sequence of array subscripts into constant zeros to start with. + const Type *ZeroIdxTy = GEPPointerTy; + for (unsigned i = 0; i != FirstConstantOper; ++i) { + if (!isa(ZeroIdxTy)) GEP1Ops[i] = GEP2Ops[i] = Constant::getNullValue(Type::UIntTy); + if (const CompositeType *CT = dyn_cast(ZeroIdxTy)) + ZeroIdxTy = CT->getTypeAtIndex(GEP1Ops[i]); + } + // We know that GEP1Ops[FirstConstantOper] & GEP2Ops[FirstConstantOper] are ok // Loop over the rest of the operands... From lattner at cs.uiuc.edu Sat Mar 4 16:34:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 16:34:38 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/CoyoteBench/ Message-ID: <200603042234.QAA06263@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/CoyoteBench: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm-test/SingleSource/Benchmarks/CoyoteBench added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Sat Mar 4 16:35:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 16:35:30 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/CoyoteBench/LICENSE.txt Makefile almabench.c fftbench.cpp huffbench.c lpbench.c Message-ID: <200603042235.QAA06342@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/CoyoteBench: LICENSE.txt added (r1.1) Makefile added (r1.1) almabench.c added (r1.1) fftbench.cpp added (r1.1) huffbench.c added (r1.1) lpbench.c added (r1.1) --- Log message: add an initial version of this benchmark to the testsuite. This may be updated in the future if I get a new version from the author --- Diffs of the changes: (+1981 -0) LICENSE.txt | 3 Makefile | 5 almabench.c | 378 +++++++++++++++++++++++++++++++ fftbench.cpp | 699 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ huffbench.c | 488 +++++++++++++++++++++++++++++++++++++++++ lpbench.c | 408 ++++++++++++++++++++++++++++++++++ 6 files changed, 1981 insertions(+) Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/LICENSE.txt diff -c /dev/null llvm-test/SingleSource/Benchmarks/CoyoteBench/LICENSE.txt:1.1 *** /dev/null Sat Mar 4 16:35:28 2006 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/LICENSE.txt Sat Mar 4 16:35:18 2006 *************** *** 0 **** --- 1,3 ---- + Written by Scott Robert Ladd. + No rights reserved. This is public domain software, for use by anyone. + Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile diff -c /dev/null llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile:1.1 *** /dev/null Sat Mar 4 16:35:30 2006 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/Makefile Sat Mar 4 16:35:18 2006 *************** *** 0 **** --- 1,5 ---- + LEVEL = ../../.. + LDFLAGS += -lm + + include $(LEVEL)/SingleSource/Makefile.singlesrc + Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/almabench.c diff -c /dev/null llvm-test/SingleSource/Benchmarks/CoyoteBench/almabench.c:1.1 *** /dev/null Sat Mar 4 16:35:30 2006 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/almabench.c Sat Mar 4 16:35:18 2006 *************** *** 0 **** --- 1,378 ---- + /* + almabench + Standard C version + 17 April 2003 + + Written by Scott Robert Ladd. + No rights reserved. This is public domain software, for use by anyone. + + A number-crunching benchmark that can be used as a fitness test for + evolving optimal compiler options via genetic algorithm. + + This program calculates the daily ephemeris (at noon) for the years + 2000-2099 using an algorithm developed by J.L. Simon, P. Bretagnon, J. + Chapront, M. Chapront-Touze, G. Francou and J. Laskar of the Bureau des + Longitudes, Paris, France), as detailed in Astronomy & Astrophysics + 282, 663 (1994) + + Note that the code herein is design for the purpose of testing + computational performance; error handling and other such "niceties" + is virtually non-existent. + + Actual benchmark results can be found at: + http://www.coyotegulch.com + + Please do not use this information or algorithm in any way that might + upset the balance of the universe or otherwise cause planets to impact + upon one another. + */ + + #include + #include + #include + #include + #include + + #define CALC_PI 3.14159265358979323846 + + static const double PI = CALC_PI; + static const double J2000 = 2451545.0; + static const double JCENTURY = 36525.0; + static const double JMILLENIA = 365250.0; + static const double TWOPI = 2.0 * CALC_PI; + static const double A2R = CALC_PI / 648000.0; + static const double R2H = 12.0 / CALC_PI; + static const double R2D = 180.0 / CALC_PI; + static const double GAUSSK = 0.01720209895; + + // number of days to include in test + #if defined(ACOVEA) + #if defined(arch_pentium4) + static const int TEST_LOOPS = 4; + #else + static const int TEST_LOOPS = 1; + #endif + #else + static const int TEST_LOOPS = 20; + #endif + + static const int TEST_LENGTH = 36525; + + // sin and cos of j2000 mean obliquity (iau 1976) + static const double sineps = 0.3977771559319137; + static const double coseps = 0.9174820620691818; + + static const double amas [8] = { 6023600.0, 408523.5, 328900.5, 3098710.0, 1047.355, 3498.5, 22869.0, 19314.0 }; + + // tables giving the mean keplerian elements, limited to t**2 terms: + // a semi-major axis (au) + // dlm mean longitude (degree and arcsecond) + // e eccentricity + // pi longitude of the perihelion (degree and arcsecond) + // dinc inclination (degree and arcsecond) + // omega longitude of the ascending node (degree and arcsecond) + static const double a [8][3] = + { { 0.3870983098, 0, 0 }, + { 0.7233298200, 0, 0 }, + { 1.0000010178, 0, 0 }, + { 1.5236793419, 3e-10, 0 }, + { 5.2026032092, 19132e-10, -39e-10 }, + { 9.5549091915, -0.0000213896, 444e-10 }, + { 19.2184460618, -3716e-10, 979e-10 }, + { 30.1103868694, -16635e-10, 686e-10 } }; + + static const double dlm[8][3] = + { { 252.25090552, 5381016286.88982, -1.92789 }, + { 181.97980085, 2106641364.33548, 0.59381 }, + { 100.46645683, 1295977422.83429, -2.04411 }, + { 355.43299958, 689050774.93988, 0.94264 }, + { 34.35151874, 109256603.77991, -30.60378 }, + { 50.07744430, 43996098.55732, 75.61614 }, + { 314.05500511, 15424811.93933, -1.75083 }, + { 304.34866548, 7865503.20744, 0.21103 } }; + + static const double e[8][3] = + { { 0.2056317526, 0.0002040653, -28349e-10 }, + { 0.0067719164, -0.0004776521, 98127e-10 }, + { 0.0167086342, -0.0004203654, -0.0000126734 }, + { 0.0934006477, 0.0009048438, -80641e-10 }, + { 0.0484979255, 0.0016322542, -0.0000471366 }, + { 0.0555481426, -0.0034664062, -0.0000643639 }, + { 0.0463812221, -0.0002729293, 0.0000078913 }, + { 0.0094557470, 0.0000603263, 0 } }; + + static const double pi[8][3] = + { { 77.45611904, 5719.11590, -4.83016 }, + { 131.56370300, 175.48640, -498.48184 }, + { 102.93734808, 11612.35290, 53.27577 }, + { 336.06023395, 15980.45908, -62.32800 }, + { 14.33120687, 7758.75163, 259.95938 }, + { 93.05723748, 20395.49439, 190.25952 }, + { 173.00529106, 3215.56238, -34.09288 }, + { 48.12027554, 1050.71912, 27.39717 } }; + + static const double dinc[8][3] = + { { 7.00498625, -214.25629, 0.28977 }, + { 3.39466189, -30.84437, -11.67836 }, + { 0, 469.97289, -3.35053 }, + { 1.84972648, -293.31722, -8.11830 }, + { 1.30326698, -71.55890, 11.95297 }, + { 2.48887878, 91.85195, -17.66225 }, + { 0.77319689, -60.72723, 1.25759 }, + { 1.76995259, 8.12333, 0.08135 } }; + + static const double omega[8][3] = + { { 48.33089304, -4515.21727, -31.79892 }, + { 76.67992019, -10008.48154, -51.32614 }, + { 174.87317577, -8679.27034, 15.34191 }, + { 49.55809321, -10620.90088, -230.57416 }, + { 100.46440702, 6362.03561, 326.52178 }, + { 113.66550252, -9240.19942, -66.23743 }, + { 74.00595701, 2669.15033, 145.93964 }, + { 131.78405702, -221.94322, -0.78728 } }; + + // tables for trigonometric terms to be added to the mean elements + // of the semi-major axes. + static const double kp[8][9] = + { { 69613.0, 75645.0, 88306.0, 59899.0, 15746.0, 71087.0, 142173.0, 3086.0, 0.0 }, + { 21863.0, 32794.0, 26934.0, 10931.0, 26250.0, 43725.0, 53867.0, 28939.0, 0.0 }, + { 16002.0, 21863.0, 32004.0, 10931.0, 14529.0, 16368.0, 15318.0, 32794.0, 0.0 }, + { 6345.0, 7818.0, 15636.0, 7077.0, 8184.0, 14163.0, 1107.0, 4872.0, 0.0 }, + { 1760.0, 1454.0, 1167.0, 880.0, 287.0, 2640.0, 19.0, 2047.0, 1454.0 }, + { 574.0, 0.0, 880.0, 287.0, 19.0, 1760.0, 1167.0, 306.0, 574.0 }, + { 204.0, 0.0, 177.0, 1265.0, 4.0, 385.0, 200.0, 208.0, 204.0 }, + { 0.0, 102.0, 106.0, 4.0, 98.0, 1367.0, 487.0, 204.0, 0.0 } }; + + static const double ca[8][9] = + { { 4.0, -13.0, 11.0, -9.0, -9.0, -3.0, -1.0, 4.0, 0.0 }, + { -156.0, 59.0, -42.0, 6.0, 19.0, -20.0, -10.0, -12.0, 0.0 }, + { 64.0, -152.0, 62.0, -8.0, 32.0, -41.0, 19.0, -11.0, 0.0 }, + { 124.0, 621.0, -145.0, 208.0, 54.0, -57.0, 30.0, 15.0, 0.0 }, + { -23437.0, -2634.0, 6601.0, 6259.0, -1507.0, -1821.0, 2620.0, -2115.0,-1489.0 }, + { 62911.0,-119919.0, 79336.0, 17814.0,-24241.0, 12068.0, 8306.0, -4893.0, 8902.0 }, + { 389061.0,-262125.0,-44088.0, 8387.0,-22976.0, -2093.0, -615.0, -9720.0, 6633.0 }, + { -412235.0,-157046.0,-31430.0, 37817.0, -9740.0, -13.0, -7449.0, 9644.0, 0.0 } }; + + static const double sa[8][9] = + { { -29.0, -1.0, 9.0, 6.0, -6.0, 5.0, 4.0, 0.0, 0.0 }, + { -48.0, -125.0, -26.0, -37.0, 18.0, -13.0, -20.0, -2.0, 0.0 }, + { -150.0, -46.0, 68.0, 54.0, 14.0, 24.0, -28.0, 22.0, 0.0 }, + { -621.0, 532.0, -694.0, -20.0, 192.0, -94.0, 71.0, -73.0, 0.0 }, + { -14614.0,-19828.0, -5869.0, 1881.0, -4372.0, -2255.0, 782.0, 930.0, 913.0 }, + { 139737.0, 0.0, 24667.0, 51123.0, -5102.0, 7429.0, -4095.0, -1976.0,-9566.0 }, + { -138081.0, 0.0, 37205.0,-49039.0,-41901.0,-33872.0,-27037.0,-12474.0,18797.0 }, + { 0.0, 28492.0,133236.0, 69654.0, 52322.0,-49577.0,-26430.0, -3593.0, 0.0 } }; + + // tables giving the trigonometric terms to be added to the mean + // elements of the mean longitudes. + static const double kq[8][10] = + { { 3086.0, 15746.0, 69613.0, 59899.0, 75645.0, 88306.0, 12661.0, 2658.0, 0.0, 0.0 }, + { 21863.0, 32794.0, 10931.0, 73.0, 4387.0, 26934.0, 1473.0, 2157.0, 0.0, 0.0 }, + { 10.0, 16002.0, 21863.0, 10931.0, 1473.0, 32004.0, 4387.0, 73.0, 0.0, 0.0 }, + { 10.0, 6345.0, 7818.0, 1107.0, 15636.0, 7077.0, 8184.0, 532.0, 10.0, 0.0 }, + { 19.0, 1760.0, 1454.0, 287.0, 1167.0, 880.0, 574.0, 2640.0, 19.0,1454.0 }, + { 19.0, 574.0, 287.0, 306.0, 1760.0, 12.0, 31.0, 38.0, 19.0, 574.0 }, + { 4.0, 204.0, 177.0, 8.0, 31.0, 200.0, 1265.0, 102.0, 4.0, 204.0 }, + { 4.0, 102.0, 106.0, 8.0, 98.0, 1367.0, 487.0, 204.0, 4.0, 102.0 } }; + + static const double cl[8][10] = + { { 21.0, -95.0, -157.0, 41.0, -5.0, 42.0, 23.0, 30.0, 0.0, 0.0 }, + { -160.0, -313.0, -235.0, 60.0, -74.0, -76.0, -27.0, 34.0, 0.0, 0.0 }, + { -325.0, -322.0, -79.0, 232.0, -52.0, 97.0, 55.0, -41.0, 0.0, 0.0 }, + { 2268.0, -979.0, 802.0, 602.0, -668.0, -33.0, 345.0, 201.0, -55.0, 0.0 }, + { 7610.0, -4997.0,-7689.0,-5841.0,-2617.0, 1115.0, -748.0, -607.0, 6074.0, 354.0 }, + { -18549.0, 30125.0,20012.0, -730.0, 824.0, 23.0, 1289.0, -352.0,-14767.0,-2062.0 }, + { -135245.0,-14594.0, 4197.0,-4030.0,-5630.0,-2898.0, 2540.0, -306.0, 2939.0, 1986.0 }, + { 89948.0, 2103.0, 8963.0, 2695.0, 3682.0, 1648.0, 866.0, -154.0, -1963.0, -283.0 } }; + + static const double sl[8][10] = + { { -342.0, 136.0, -23.0, 62.0, 66.0, -52.0, -33.0, 17.0, 0.0, 0.0 }, + { 524.0, -149.0, -35.0, 117.0, 151.0, 122.0, -71.0, -62.0, 0.0, 0.0 }, + { -105.0, -137.0, 258.0, 35.0, -116.0, -88.0, -112.0, -80.0, 0.0, 0.0 }, + { 854.0, -205.0, -936.0, -240.0, 140.0, -341.0, -97.0, -232.0, 536.0, 0.0 }, + { -56980.0, 8016.0, 1012.0, 1448.0,-3024.0,-3710.0, 318.0, 503.0, 3767.0, 577.0 }, + { 138606.0,-13478.0,-4964.0, 1441.0,-1319.0,-1482.0, 427.0, 1236.0, -9167.0,-1918.0 }, + { 71234.0,-41116.0, 5334.0,-4935.0,-1848.0, 66.0, 434.0,-1748.0, 3780.0, -701.0 }, + { -47645.0, 11647.0, 2166.0, 3194.0, 679.0, 0.0, -244.0, -419.0, -2531.0, 48.0 } }; + + //--------------------------------------------------------------------------- + // Normalize angle into the range -pi <= A < +pi. + double anpm (double a) + { + double w = fmod(a,TWOPI); + + if (fabs(w) >= PI) + w = w - ((a < 0) ? -TWOPI : TWOPI); + + return w; + } + + //--------------------------------------------------------------------------- + // The reference frame is equatorial and is with respect to the + // mean equator and equinox of epoch j2000. + void planetpv (double epoch[2], int np, double pv[2][3]) + { + // working storage + int i, j, k; + double t, da, dl, de, dp, di, doh, dmu, arga, argl, am; + double ae, dae, ae2, at, r, v, si2, xq, xp, tl, xsw; + double xcw, xm2, xf, ci2, xms, xmc, xpxq2, x, y, z; + + // time: julian millennia since j2000. + t = ((epoch[0] - J2000) + epoch[1]) / JMILLENIA; + + // compute the mean elements. + da = a[np][0] + (a[np][1] + a[np][2] * t ) * t; + dl = (3600.0 * dlm[np][0] + (dlm[np][1] + dlm[np][2] * t ) * t ) * A2R; + de = e[np][0] + (e[np][1] + e[np][2] * t ) * t; + dp = anpm((3600.0 * pi[np][0] + (pi[np][1] + pi[np][2] * t ) * t ) * A2R ); + di = (3600.0 * dinc[np][0] + (dinc[np][1] + dinc[np][2] * t ) * t ) * A2R; + doh = anpm((3600.0 * omega[np][0] + (omega[np][1] + omega[np][2] * t ) * t ) * A2R ); + + // apply the trigonometric terms. + dmu = 0.35953620 * t; + + for (k = 0; k < 8; ++k) + { + arga = kp[np][k] * dmu; + argl = kq[np][k] * dmu; + da = da + (ca[np][k] * cos(arga) + sa[np][k] * sin(arga)) * 0.0000001; + dl = dl + (cl[np][k] * cos(argl) + sl[np][k] * sin(argl)) * 0.0000001; + } + + arga = kp[np][8] * dmu; + da = da + t * (ca[np][8] * cos(arga) + sa[np][8] * sin(arga)) * 0.0000001; + + for (k = 8; k <= 9; ++k) + { + argl = kq[np][k] * dmu; + dl = dl + t * ( cl[np][k] * cos(argl) + sl[np][k] * sin(argl) ) * 0.0000001; + } + + dl = fmod(dl,TWOPI); + + // iterative solution of kepler's equation to get eccentric anomaly. + am = dl - dp; + ae = am + de * sin(am); + k = 0; + + while (1) + { + dae = (am - ae + de * sin(ae)) / (1.0 - de * cos(ae)); + ae = ae + dae; + k = k + 1; + + if ((k >= 10) || (fabs(dae) < 1e-12)) + break; + } + + // true anomaly. + ae2 = ae / 2.0; + at = 2.0 * atan2(sqrt((1.0 + de)/(1.0 - de)) * sin(ae2), cos(ae2)); + + // distance (au) and speed (radians per day). + r = da * (1.0 - de * cos(ae)); + v = GAUSSK * sqrt((1.0 + 1.0 / amas[np] ) / (da * da * da)); + + si2 = sin(di / 2.0); + xq = si2 * cos(doh); + xp = si2 * sin(doh); + tl = at + dp; + xsw = sin(tl); + xcw = cos(tl); + xm2 = 2.0 * (xp * xcw - xq * xsw ); + xf = da / sqrt(1.0 - de*de); + ci2 = cos(di / 2.0); + xms = (de * sin(dp) + xsw) * xf; + xmc = (de * cos(dp) + xcw) * xf; + xpxq2 = 2.0 * xp * xq; + + // position (j2000 ecliptic x,y,z in au). + x = r * (xcw - xm2 * xp); + y = r * (xsw + xm2 * xq); + z = r * (-xm2 * ci2); + + // rotate to equatorial. + pv[0][0] = x; + pv[0][1] = y * coseps - z * sineps; + pv[0][2] = y * sineps + z * coseps; + + // velocity (j2000 ecliptic xdot,ydot,zdot in au/d). + x = v * ((-1.0 + 2.0 * xp * xp) * xms + xpxq2 * xmc); + y = v * (( 1.0 - 2.0 * xq * xq ) * xmc - xpxq2 * xms); + z = v * (2.0 * ci2 * (xp * xms + xq * xmc)); + + // rotate to equatorial. + pv[1][0] = x; + pv[1][1] = y * coseps - z * sineps; + pv[1][2] = y * sineps + z * coseps; + } + + //--------------------------------------------------------------------------- + // Computes RA, Declination, and distance from a state vector returned by + // planetpv. + void radecdist(double state[2][3], double rdd[3]) + { + // distance + rdd[2] = sqrt(state[0][0] * state[0][0] + state[0][1] * state[0][1] + state[0][2] * state[0][2]); + + // RA + rdd[0] = atan2(state[0][1], state[0][0]) * R2H; + if (rdd[0] < 0.0) rdd[0] += 24.0; + + // Declination + rdd[1] = asin(state[0][2] / rdd[2]) * R2D; + } + + //--------------------------------------------------------------------------- + // Entry point + // Calculate RA and Dec for noon on every day in 1900-2100 + int main(int argc, char ** argv) + { + int i, n, p; + double jd[2]; + double pv[2][3]; + double position[3]; + bool ga_testing = false; + + // do we have verbose output? + if (argc > 1) + { + for (i = 1; i < argc; ++i) + { + if (!strcmp(argv[1],"-ga")) + { + ga_testing = true; + break; + } + } + } + + // get starting time + + // main loop + for (i = 0; i < TEST_LOOPS; ++i) + { + jd[0] = J2000; + jd[1] = 0.0; + + for (n = 0; n < TEST_LENGTH; ++n) + { + jd[0] += 1.0; + + for (p = 0; p < 8; ++p) + { + planetpv(jd,p,pv); + radecdist(pv,position); + } + } + } + + // get final time + + // report runtime + + fflush(stdout); + + return 0; + } Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/fftbench.cpp diff -c /dev/null llvm-test/SingleSource/Benchmarks/CoyoteBench/fftbench.cpp:1.1 *** /dev/null Sat Mar 4 16:35:30 2006 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/fftbench.cpp Sat Mar 4 16:35:18 2006 *************** *** 0 **** --- 1,699 ---- + /* + fftbench + Standard C++ version + 10 May 2003 + + Written by Scott Robert Ladd. + No rights reserved. This is public domain software, for use by anyone. + + A number-crunching benchmark that can be used as a fitness test for + evolving optimal compiler options via genetic algorithm. + + A simplified version of the FFT component from my standard libcoyote + library, this benchmark test FFT performance on complex values. + + Note that the code herein is design for the purpose of testing + computational performance; error handling and other such "niceties" + is virtually non-existent. + + Actual benchmark results can be found at: + http://www.coyotegulch.com + + Please do not use this information or algorithm in any way that might + upset the balance of the universe or to produce imaginary friends for + imaginary numbers. + */ + + #include + #include + #include + #include + #include + #include + #include + + using namespace std; + + //--------------------------------------------------------------------------- + // number of loops to perform + #if defined(ACOVEA) + #if defined(arch_pentium4) + static const int TEST_SIZE = 262144; + #else + static const int TEST_SIZE = 131072; + #endif + #else + static const int TEST_SIZE = 2097152; + #endif + + //--------------------------------------------------------------------------- + // embedded random number generator; ala Park and Miller + static double random_double() + { + static long seed = 1325; + static const long IA = 16807; + static const long IM = 2147483647; + static const double AM = 4.65661287525E-9; + static const long IQ = 127773; + static const long IR = 2836; + static const long MASK = 123459876; + + long k; + double result; + + seed ^= MASK; + k = seed / IQ; + seed = IA * (seed - k * IQ) - IR * k; + + if (seed < 0) + seed += IM; + + result = AM * seed; + seed ^= MASK; + + return result; + } + + //--------------------------------------------------------------------------- + template + class polynomial + { + public: + // creation constructor, uninitialized (coefficients will be unknown values) + polynomial(size_t degree); + + // creation constructor, with initialization from array + polynomial(size_t degree, const T * coefficients); + + // creation constructor, with single-value initialization constructor + polynomial(size_t degree, const T & value); + + // copy constructor + polynomial(const polynomial & source); + + // destructor + virtual ~polynomial(); + + // assignment + polynomial & operator = (const polynomial & source); + + // initialize to specific value + void initialize(const T & value = T(0)); + + // increase polynomial length + polynomial & stretch(size_t degrees); + + // interrogate for degree + size_t degree() const + { + return m_degree; + } + + // get specific coefficient + T get(size_t term) const; + + T & operator [] (size_t term); + + // evaluate for a specific value + T operator() (const T & x) const; + + // unitary operators + polynomial operator - () const; + polynomial operator + () const; + + // binary mathematical operators + polynomial operator + (const polynomial & poly) const; + polynomial operator - (const polynomial & poly) const; + + // constant required by FFT routines + static const complex PI2I; + + // returns largest power of two that holds n + static size_t log2(size_t n); + + // reverses a sequence of bits + static size_t flip_bits(size_t k, size_t bits); + + // stretches the length of a polynomial to a power of two + size_t stretch_fft(); + + // performs a reverse-bit copy of a polynomial into a new polynomial< complex > + static polynomial< complex > bit_reverse(const polynomial & poly); + static polynomial< complex > bit_reverse(const polynomial< complex > & poly); + + // Fast Fourier Transform of polynomial to polynomial< complex > + static polynomial< complex > fft(const polynomial & poly); + + // inverse FFT of polynomial< complex > to polynomial + static polynomial< complex > inverse_fft(const polynomial< complex > & poly); + + // multiplication via FFT + polynomial operator * (const polynomial & poly) const; + + // shorthand mathematical operators + polynomial & operator += (const polynomial & poly); + polynomial & operator -= (const polynomial & poly); + polynomial & operator *= (const polynomial & poly); + + protected: + // coefficients + T * m_coeff; + + // number of terms + size_t m_degree; + + // acquire resources + void acquire(); + + // release resources + void release(); + + // deep copy + void deep_copy(const T * source); + }; + + // acquire resources + template + inline void polynomial::acquire() + { + m_coeff = new T [m_degree]; + } + + // release resources + template + inline void polynomial::release() + { + delete [] m_coeff; + } + + // deep copy + template + inline void polynomial::deep_copy(const T * source) + { + for (size_t n = 0; n < m_degree; ++n) + m_coeff[n] = source[n]; + } + + // initialize to specific value + template + inline void polynomial::initialize(const T & value) + { + for (size_t n = 0; n < m_degree; ++n) + m_coeff[n] = value; + } + + // creation constructor, uninitialized (coefficients will be unknown values) + template + polynomial::polynomial(size_t degree) + : m_coeff(NULL), + m_degree(degree) + { + acquire(); + } + + // creation constructor, with possible initialization from array + template + polynomial::polynomial(size_t degree, const T * coefficients) + : m_coeff(NULL), + m_degree(degree) + { + acquire(); + + if (coefficients != NULL) + deep_copy(coefficients); + } + + // creation constructor, with single-value initialization constructor + template + polynomial::polynomial(size_t degree, const T & value) + : m_coeff(NULL), + m_degree(degree) + { + acquire(); + initialize(value); + } + + // copy constructor + template + polynomial::polynomial(const polynomial & source) + : m_coeff(NULL), + m_degree(source.m_degree) + { + acquire(); + deep_copy(source.m_coeff); + } + + // destructor + template + polynomial::~polynomial() + { + release(); + } + + // assignment + template + polynomial & polynomial::operator = (const polynomial & source) + { + if (m_degree != source.m_degree) + { + release(); + + m_degree = source.m_degree; + acquire(); + } + + deep_copy(source.m_coeff); + + return *this; + } + + // increase polynomial length + template + polynomial & polynomial::stretch(size_t degrees) + { + if (degrees != 0) + { + T * old_coeff = m_coeff; + size_t old_degree = m_degree; + + m_degree += degrees; + acquire(); + + size_t n = 0; + + for (; n < old_degree; ++n) + m_coeff[n] = old_coeff[n]; + + for (; n < m_degree; ++n) + m_coeff[n] = T(0); + } + + return *this; + } + + // get specific coefficient + template + T polynomial::get(size_t term) const + { + return m_coeff[term]; + } + + template + T & polynomial::operator [] (size_t term) + { + return m_coeff[term]; + } + + // evaluate for a specific value + template + T polynomial::operator() (const T & x) const + { + // using Horner's Rule + T y = m_coeff[m_degree - 1]; + + size_t i = m_degree - 2; + + while (true) + { + y = x * y + m_coeff[i]; + + if (i > 0) + --i; + else + break; + } + + return y; + } + + // unitary operators + template + polynomial polynomial::operator - () const + { + polynomial result(m_degree); // uninitialized + + for (size_t n = 0; n < m_degree; ++n) + result.m_coeff[n] = -m_coeff[n]; + + return result; + } + + template + polynomial polynomial::operator + () const + { + return polynomial(*this); + } + + // binary mathematical operators + template + polynomial polynomial::operator + (const polynomial & poly) const + { + if (m_degree >= poly.m_degree) + { + polynomial result(*this); + + for (size_t n = 0; n < m_degree; ++n) + result.m_coeff[n] += poly.m_coeff[n]; + + return result; + } + else + { + polynomial result(poly); + + for (size_t n = 0; n < m_degree; ++n) + result.m_coeff[n] += m_coeff[n]; + + return result; + } + } + + template + polynomial polynomial::operator - (const polynomial & poly) const + { + if (m_degree >= poly.m_degree) + { + polynomial result(*this); + + for (size_t n = 0; n < m_degree; ++n) + result.m_coeff[n] -= poly.m_coeff[n]; + + return result; + } + else + { + polynomial result(poly); + + for (size_t n = 0; n < m_degree; ++n) + result.m_coeff[n] -= m_coeff[n]; + + return result; + } + } + + // constant required by FFT routines + template + const complex polynomial::PI2I(0.0,6.283185307179586); + + // returns largest power of two that holds n + template + size_t polynomial::log2(size_t n) + { + // returns 1 if n == 0! + size_t x = 1, c = 0; + + while (x < n) + { + ++c; + x <<= 1; + + if (x == 0) + break; + } + + return c; + } + + // reverses a sequence of bits + template + size_t polynomial::flip_bits(size_t k, size_t bits) + { + size_t lm = 1 << (bits - 1); + size_t rm = 1; + size_t r = 0; + + while (lm) + { + if (k & rm) + r |= (lm); + + lm >>= 1; + rm <<= 1; + } + + return r; + } + + // stretches the length of a polynomial to a power of two + template + size_t polynomial::stretch_fft() + { + size_t n = 1; + + while (true) + { + if (m_degree <= n) + break; + + n <<= 1; + + if (n == 0) + throw overflow_error("overflow in fft polynomial stretch"); + } + + n <<= 1; + n -= m_degree; + + if (n > 0) + stretch(n); + + return n; + } + + // performs a reverse-bit copy of a polynomial into a new polynomial< complex > + template + polynomial< complex > polynomial::bit_reverse(const polynomial & poly) + { + size_t b = log2(poly.degree()); + + polynomial< complex > result(poly.degree()); + + for (size_t n = 0; n < poly.degree(); ++n) + result[flip_bits(n,b)] = poly.get(n); + + return result; + } + + // performs a reverse-bit copy of a polynomial into a new polynomial< complex > + template + polynomial< complex > polynomial::bit_reverse(const polynomial< complex > & poly) + { + size_t b = log2(poly.degree()); + + polynomial< complex > result(poly.degree()); + + for (size_t n = 0; n < poly.degree(); ++n) + result[flip_bits(n,b)] = poly.get(n); + + return result; + } + + // Fast Fourier Transform of polynomial to polynomial< complex > + template + polynomial< complex > polynomial::fft(const polynomial & poly) + { + size_t nl = log2(poly.degree()); + size_t j, k, m, m2, s; + complex wm, w, t, u; + + polynomial< complex > result = bit_reverse(poly); + + m = 2; + m2 = 1; + + for (s = 0; s < nl; ++s) + { + wm = exp(PI2I / complex(m)); + w = 1.0; + + for (j = 0; j <= (m2 - 1); ++j) + { + for (k = j; k <= poly.degree() - 1; k += m) + { + t = w * result[k + m2]; + u = result[k]; + result[k] = u + t; + result[k + m2] = u - t; + } + + w *= wm; + } + + m <<= 1; + m2 <<= 1; + } + + return result; + } + + // inverse FFT of polynomial< complex > to polynomial + template + polynomial< complex > polynomial::inverse_fft(const polynomial< complex > & poly) + { + size_t nl = log2(poly.degree()); + size_t j, k, m, m2, s; + complex wm, w, t, u; + + polynomial< complex > result = bit_reverse(poly); + + m = 2; + m2 = 1; + + for (s = 0; s < nl; ++s) + { + wm = exp(-PI2I / complex(m)); + w = 1.0; + + for (j = 0; j <= (m2 - 1); ++j) + { + for (k = j; k <= poly.degree() - 1; k += m) + { + t = w * result[k + m2]; + u = result[k]; + result[k] = u + t; + result[k + m2] = u - t; + } + + w *= wm; + } + + m <<= 1; + m2 <<= 1; + } + + for (j = 0; j < poly.degree(); ++j) + result[j] /= double(poly.degree()); + + return result; + } + + // multiplication by FFT + template + polynomial polynomial::operator * (const polynomial & poly) const + { + #if defined(BRUTE_FORCE) + // brute force algorithm + if (m_degree != poly.m_degree) + throw domain_error("can not multiply two polynomials with different lengths"); + + polynomial result(2 * m_degree - 1, T(0)); + + for (size_t n1 = 0; n1 < m_degree; ++n1) + for (size_t n2 = 0; n2 < m_degree; ++n2) + result.m_coeff[n1 + n2] += m_coeff[n1] * poly.m_coeff[n2]; + #else + // duplicate p1 and p2 to preserve original objects + polynomial a1(*this); + polynomial a2(poly); + + // expand polynomials to next-largest power of two + if (a1.degree() > a2.degree()) + a2.stretch(a1.stretch_fft()); + else + a1.stretch(a2.stretch_fft()); + + // FFT polynomials + polynomial< complex > dft1 = fft(a1); + polynomial< complex > dft2 = fft(a2); + + // multiply coefficients + size_t n2 = a1.degree(); + + for (size_t k = 0; k < n2; ++k) + dft1[k] *= dft2[k]; + + // inverse DFT to obtain result + dft2 = inverse_fft(dft1); + + // convert back to complex + --n2; + polynomial result(n2); + + for (size_t k = 0; k < n2; ++k) + result[k] = dft2[k].real(); + #endif + + return result; + } + + // shorthand mathematical operators + template + polynomial & polynomial::operator += (const polynomial & poly) + { + size_t length = (m_degree <= poly.m_degree) ? m_degree : poly.m_degree; + + for (size_t n = 0; n < length; ++n) + m_coeff[n] += poly.m_coeff[n]; + + return *this; + } + + template + polynomial & polynomial::operator -= (const polynomial & poly) + { + size_t length = (m_degree <= poly.m_degree) ? m_degree : poly.m_degree; + + for (size_t n = 0; n < length; ++n) + m_coeff[n] -= poly.m_coeff[n]; + + return *this; + } + + template + polynomial & polynomial::operator *= (const polynomial & poly) + { + *this = (*this) * poly; + } + + //--------------------------------------------------------------------------- + // Entry point + int main(int argc, char ** argv) + { + // are we testing using a genetic algorithm? + bool ga_testing = false; + + if (argc > 1) + { + for (int i = 1; i < argc; ++i) + { + if (!strcmp(argv[1],"-ga")) + { + ga_testing = true; + break; + } + } + } + + // generate random polynomials + polynomial poly1(TEST_SIZE); + polynomial poly2(TEST_SIZE); + polynomial poly3(TEST_SIZE * 2 - 1); + + for (int n = 0; n < TEST_SIZE; ++n) + { + poly1[n] = random_double(); + poly2[n] = random_double(); + } + + // get starting time + //struct timespec start, stop; + //clock_gettime(CLOCK_REALTIME,&start); + + // what we're timing + poly3 = poly1 * poly2; + + // get final time + //clock_gettime(CLOCK_REALTIME,&stop); + double run_time = 0; + //(stop.tv_sec - start.tv_sec) + (double)(stop.tv_nsec - start.tv_nsec) / 1000000000.0; + + // report runtime + if (ga_testing) + cout << run_time; + else + cout << "\nfftbench (Std. C++) run time: " << run_time << "\n\n"; + + cout.flush(); + + return 0; + } Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/huffbench.c diff -c /dev/null llvm-test/SingleSource/Benchmarks/CoyoteBench/huffbench.c:1.1 *** /dev/null Sat Mar 4 16:35:30 2006 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/huffbench.c Sat Mar 4 16:35:18 2006 *************** *** 0 **** --- 1,488 ---- + /* + huffbench + Standard C version + 17 April 2003 + + Written by Scott Robert Ladd (scott at coyotegulch.com) + No rights reserved. This is public domain software, for use by anyone. + + A data compression benchmark that can also be used as a fitness test + for evolving optimal compiler options via genetic algorithm. + + This program implements the Huffman compression algorithm. The code + is not the tightest or fastest possible C code; rather, it is a + relatively straight-forward implementation of the algorithm, + providing opportunities for an optimizer to "do its thing." + + Note that the code herein is design for the purpose of testing + computational performance; error handling and other such "niceties" + is virtually non-existent. + + Actual benchmark results can be found at: + http://www.coyotegulch.com + + Please do not use this information or algorithm in any way that might + upset the balance of the universe or otherwise cause the creation of + singularities. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + + // embedded random number generator; ala Park and Miller + static long seed = 1325; + static const long IA = 16807; + static const long IM = 2147483647; + static const long IQ = 127773; + static const long IR = 2836; + static const long MASK = 123459876; + + // return index between 0 and 3 + static size_t random4() + { + long k; + size_t result; + + seed ^= MASK; + k = seed / IQ; + seed = IA * (seed - k * IQ) - IR * k; + + if (seed < 0L) + seed += IM; + + result = (size_t)(seed % 32L); + seed ^= MASK; + + return result; + } + + #if defined(ACOVEA) + #if defined(arch_pentium4) + static const int NUM_LOOPS = 5; + static const int TEST_SIZE = 10000000; + #else + static const int NUM_LOOPS = 2; + static const int TEST_SIZE = 5000000; + #endif + #else + static const int NUM_LOOPS = 30; + static const int TEST_SIZE = 10000000; + #endif + + typedef unsigned long bits32; + typedef unsigned char byte; + + // compressed (encoded) data + + byte * generate_test_data(size_t n) + { + char * codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; + + byte * result = (byte *)malloc(n); + byte * ptr = result; + + int i; + for (i = 0; i < n; ++i) + { + *ptr = (byte)codes[random4()]; + ++ptr; + } + + return result; + } + + // utility function for processing compression trie + static void heap_adjust(size_t * freq, size_t * heap, int n, int k) + { + // this function compares the values in the array + // 'freq' to order the elements of 'heap' according + // in an inverse heap. See the chapter on priority + // queues and heaps for more explanation. + int j; + + --heap; + + int v = heap[k]; + + while (k <= (n / 2)) + { + j = k + k; + + if ((j < n) && (freq[heap[j]] > freq[heap[j+1]])) + ++j; + + if (freq[v] < freq[heap[j]]) + break; + + heap[k] = heap[j]; + k = j; + } + + heap[k] = v; + } + + // Huffman compression/decompression function + void compdecomp(byte * data, size_t data_len) + { + size_t i, j, n, mask; + bits32 k, t; + byte c; + byte * cptr; + byte * dptr = data; + + /* + COMPRESSION + */ + + // allocate data space + byte * comp = (byte *)malloc(data_len + 1); + + size_t freq[512]; // allocate frequency table + size_t heap[256]; // allocate heap + int link[512]; // allocate link array + bits32 code[256]; // huffman codes + byte clen[256]; // bit lengths of codes + + memset(comp,0,sizeof(byte) * (data_len + 1)); + memset(freq,0,sizeof(size_t) * 512); + memset(heap,0,sizeof(size_t) * 256); + memset(link,0,sizeof(int) * 512); + memset(code,0,sizeof(bits32) * 256); + memset(clen,0,sizeof(byte) * 256); + + // count frequencies + for (i = 0; i < data_len; ++i) + { + ++freq[(size_t)(*dptr)]; + ++dptr; + } + + // create indirect heap based on frequencies + n = 0; + + for (i = 0; i < 256; ++i) + { + if (freq[i]) + { + heap[n] = i; + ++n; + } + } + + for (i = n; i > 0; --i) + heap_adjust(freq,heap,n,i); + + // generate a trie from heap + size_t temp; + + // at this point, n contains the number of characters + // that occur in the data array + while (n > 1) + { + // take first item from top of heap + --n; + temp = heap[0]; + heap[0] = heap[n]; + + // adjust the heap to maintain properties + heap_adjust(freq,heap,n,1); + + // in upper half of freq array, store sums of + // the two smallest frequencies from the heap + freq[256 + n] = freq[heap[0]] + freq[temp]; + link[temp] = 256 + n; // parent + link[heap[0]] = -256 - n; // left child + heap[0] = 256 + n; // right child + + // adjust the heap again + heap_adjust(freq,heap,n,1); + } + + link[256 + n] = 0; + + // generate codes + size_t m, x, maxx = 0, maxi = 0; + int l; + + for (m = 0; m < 256; ++m) + { + if (!freq[m]) // character does not occur + { + code[m] = 0; + clen[m] = 0; + } + else + { + i = 0; // length of current code + j = 1; // bit being set in code + x = 0; // code being built + l = link[m]; // link in trie + + while (l) // while not at end of trie + { + if (l < 0) // left link (negative) + { + x += j; // insert 1 into code + l = -l; // reverse sign + } + + l = link[l]; // move to next link + j <<= 1; // next bit to be set + ++i; // increment code length + } + + code[m] = (unsigned long)x; // save code + clen[m] = (unsigned char)i; // save code len + + // keep track of biggest key + if (x > maxx) + maxx = x; + + // keep track of longest key + if (i > maxi) + maxi = i; + } + } + + // make sure longest codes fit in unsigned long-bits + if (maxi > (sizeof(unsigned long) * 8)) + { + fprintf(stderr,"error: bit code overflow\n"); + exit(1); + } + + // encode data + size_t comp_len = 0; // number of data_len output + char bout = 0; // byte of encoded data + int bit = -1; // count of bits stored in bout + dptr = data; + + // watch for one-value file! + if (maxx == 0) + { + fprintf(stderr,"error: file has only one value!\n"); + exit(1); + } + + for (j = 0; j < data_len; ++j) + { + // start copying at first bit of code + mask = 1 << (clen[(*dptr)] - 1); + + // copy code bits + for (i = 0; i < clen[(*dptr)]; ++i) + { + if (bit == 7) + { + // store full output byte + comp[comp_len] = bout; + ++comp_len; + + // check for output longer than input! + if (comp_len == data_len) + { + fprintf(stderr,"error: no compression\n"); + exit(1); + } + + bit = 0; + bout = 0; + } + else + { + // move to next bit + ++bit; + bout <<= 1; + } + + if (code[(*dptr)] & mask) + bout |= 1; + + mask >>= 1; + } + + ++dptr; + } + + // output any incomplete data_len and bits + bout <<= (7 - bit); + comp[comp_len] = bout; + ++comp_len; + + // printf("data len = %u\n",data_len); + // printf("comp len = %u\n",comp_len); + + /* + DECOMPRESSION + */ + + // allocate heap2 + bits32 heap2[256]; + + // allocate output character buffer + char outc[256]; + + // initialize work areas + memset(heap2,0,256 * sizeof(bits32)); + + // create decode table as trie heap2 + char * optr = outc; + + for (j = 0; j < 256; ++j) + { + (*optr) = (char)j; + ++optr; + + // if code exists for this byte + if (code[j] | clen[j]) + { + // begin at first code bit + k = 0; + mask = 1 << (clen[j] - 1); + + // find proper node, using bits in + // code as path. + for (i = 0; i < clen[j]; ++i) + { + k = k * 2 + 1; // right link + + if (code[j] & mask) + ++k; // go left + + mask >>= 1; // next bit + } + + heap2[j] = k; // store link in heap2 + } + } + + // sort outc based on heap2 + for (i = 1; i < 256; ++i) + { + t = heap2[i]; + c = outc[i]; + j = i; + + while ((j) && (heap2[j-1] > t)) + { + heap2[j] = heap2[j - 1]; + outc[j] = outc[j - 1]; + --j; + } + + heap2[j] = t; + outc[j] = c; + } + + // find first character in table + for (j = 0; heap2[j] == 0; ++j) ; + + // decode data + k = 0; // link in trie + i = j; + mask = 0x80; + n = 0; + cptr = comp; + dptr = data; + + while (n < data_len) + { + k = k * 2 + 1; // right link + + if ((*cptr) & mask) + ++k; // left link if bit on + + // search heap2 until link >= k + while (heap2[i] < k) + ++i; + + // code matches, character found + if (k == heap2[i]) + { + (*dptr) = outc[i]; + ++dptr; + ++n; + k = 0; + i = j; + } + + // move to next bit + if (mask > 1) + mask >>= 1; + else // code extends into next byte + { + mask = 0x80; + ++cptr; + } + } + + // remove work areas + free(comp); + } + + int main(int argc, char ** argv) + { + int i; + + // do we have verbose output? + bool ga_testing = false; + + if (argc > 1) + { + for (i = 1; i < argc; ++i) + { + if (!strcmp(argv[1],"-ga")) + { + ga_testing = true; + break; + } + } + } + + // initialization + byte * test_data = generate_test_data(TEST_SIZE); + + /* + FILE * before = fopen("before","wb"); + fwrite(test_data,1,TEST_SIZE,before); + fclose(before); + */ + + // get starting time + //struct timespec start, stop; + //clock_gettime(CLOCK_REALTIME,&start); + + // what we're timing + for (i = 0; i < NUM_LOOPS; ++i) + compdecomp(test_data,TEST_SIZE); + + // calculate run time + //clock_gettime(CLOCK_REALTIME,&stop); + double run_time = 0; //(stop.tv_sec - start.tv_sec) + (double)(stop.tv_nsec - start.tv_nsec) / 1000000000.0; + + /* + FILE * after = fopen("after","wb"); + fwrite(test_data,1,TEST_SIZE,after); + fclose(after); + */ + + // release resources + free(test_data); + + // report runtime + if (ga_testing) + fprintf(stdout,"%f",run_time); + else + fprintf(stdout,"\nhuffbench (Std. C) run time: %f\n\n",run_time); + + fflush(stdout); + + // done + return 0; + } Index: llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c diff -c /dev/null llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c:1.1 *** /dev/null Sat Mar 4 16:35:30 2006 --- llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c Sat Mar 4 16:35:18 2006 *************** *** 0 **** --- 1,408 ---- + /* + lpbench + Standard C version + 17 April 2003 + + Written by Scott Robert Ladd (scott at coyotegulch.com) + No rights reserved. This is public domain software, for use by anyone. + + A number-crunching benchmark that can be used as a fitness test for + evolving optimal compiler options via genetic algorithm. + + This program is a modernized version of the classic Linpack + benchmark. My implementation is based on Bonnie Toy's translation + of the original Fortran source code, including modifications by Jack + Dongarra and Roy Longbottom. + + I've updated the code as follows: + + 1) ANSI C code + 2) A timing mechanism based on the POSIX clock_gettime() function + 3) Replaces C's rather weak random number generator + 4) Compute results for a 2500x2500 (6.25 million element) matrix + + Note that the code herein is design for the purpose of testing + computational performance; error handling and other such "niceties" + is virtually non-existent. + + Actual benchmark results can be found at: + http://www.coyotegulch.com + + Please do not use this information or algorithm in any way that might + upset the balance of the universe or otherwise cause a disturbance in + the space-time continuum. + */ + + #include + #include + #include + #include + #include + #include + + // embedded random number generator; ala Park and Miller + static long seed = 1325; + static const long IA = 16807; + static const long IM = 2147483647; + static const double AM = 4.65661287525E-10; + static const long IQ = 127773; + static const long IR = 2836; + static const long MASK = 123459876; + + static double random_double() + { + long k; + double result; + + seed ^= MASK; + k = seed / IQ; + seed = IA * (seed - k * IQ) - IR * k; + + if (seed < 0) + seed += IM; + + result = AM * seed; + seed ^= MASK; + + return result; + } + + #if defined(ACOVEA) + #if defined(arch_pentium4) + static const int N = 1000; + static const int NM1 = 999; // N - 1 + static const int NP1 = 1001; // N + 1 + #else + static const int N = 600; + static const int NM1 = 599; // N - 1 + static const int NP1 = 601; // N + 1 + #endif + #else + static const int N = 2000; + static const int NM1 = 1999; // N - 1 + static const int NP1 = 2001; // N + 1 + #endif + + // benchmark code + void matgen (double ** a, double * b) + { + // fill arrays + int i, j; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + a[j][i] = random_double(); + + for (i = 0; i < N; i++) + b[i] = 0.0; + + for (j = 0; j < N; j++) + for (i = 0; i < N; i++) + b[i] += a[j][i]; + } + + // finds the index of element having max. absolute value. + int idamax(int n, double * dx, int dx_off, int incx) + { + double dmax, dtemp; + int i, ix, itemp = 0; + + if (n < 1) + itemp = -1; + else + { + if (n ==1) + itemp = 0; + else + { + if (incx != 1) + { + // code for increment not equal to 1 + dmax = fabs(dx[dx_off]); + ix = 1 + incx; + + for (i = 1; i < n; i++) + { + dtemp = fabs(dx[ix + dx_off]); + + if (dtemp > dmax) + { + itemp = i; + dmax = dtemp; + } + + ix += incx; + } + } + else + { + // code for increment equal to 1 + itemp = 0; + dmax = fabs(dx[dx_off]); + + for (i = 1; i < n; i++) + { + dtemp = fabs(dx[i + dx_off]); + + if (dtemp > dmax) + { + itemp = i; + dmax = dtemp; + } + } + } + } + } + + return itemp; + } + + // forms the dot product of two vectors. + static double ddot(int n, double * dx, int dx_off, int incx, double * dy, int dy_off, int incy) + { + int i; + double dtemp = 0.0; + + if (n > 0) + { + if (incx != 1 || incy != 1) + { + // code for unequal increments or equal increments not equal to 1 + int ix = 0; + int iy = 0; + + if (incx < 0) + ix = (-n + 1) * incx; + + if (incy < 0) + iy = (-n + 1) * incy; + + for (i = 0;i < n; i++) + { + dtemp += dx[ix + dx_off] * dy[iy + dy_off]; + ix += incx; + iy += incy; + } + } + else + { + // code for both increments equal to 1 + for (i=0; i < n; i++) + dtemp += dx[i + dx_off] * dy[i + dy_off]; + } + } + + return(dtemp); + } + + // scales a vector by a constant. + void dscal(int n, double da, double * dx, int dx_off, int incx) + { + int i; + + if (n > 0) + { + if (incx != 1) + { + // code for increment not equal to 1 + int nincx = n * incx; + + for (i = 0; i < nincx; i += incx) + dx[i + dx_off] *= da; + } + else + { + // code for increment equal to 1 + for (i = 0; i < n; i++) + dx[i + dx_off] *= da; + } + } + } + + // constant times a vector plus a vector. + void daxpy(int n, double da, double * dx, int dx_off, int incx, double * dy, int dy_off, int incy) + { + int i; + + if ((n > 0) && (da != 0)) + { + if (incx != 1 || incy != 1) + { + // code for unequal increments or equal increments not equal to 1 + int ix = 0; + int iy = 0; + + if (incx < 0) + ix = (1 - n) * incx; + + if (incy < 0) + iy = (1 - n) * incy; + + for (i = 0; i < n; i++) + { + dy[iy + dy_off] += da * dx[ix + dx_off]; + ix += incx; + iy += incy; + } + + return; + } + else + { + // code for both increments equal to 1 + for (i = 0; i < n; i++) + dy[i + dy_off] += da * dx[i + dx_off]; + } + } + } + + // Factors a double precision matrix by gaussian elimination. + void dgefa(double ** a, int * ipvt) + { + double temp; + int k, j; + + for (k = 0; k < NM1; k++) + { + double * col_k = a[k]; + int kp1 = k + 1; + + // find l = pivot index + int l = idamax(N - k, col_k, k, 1) + k; + ipvt[k] = l; + + // zero pivot implies this column already triangularized + if (col_k[l] != 0) + { + // interchange if necessary + if (l != k) + { + temp = col_k[l]; + col_k[l] = col_k[k]; + col_k[k] = temp; + } + + // compute multipliers + temp = -1.0 / col_k[k]; + dscal(N - kp1, temp, col_k, kp1, 1); + + // row elimination with column indexing + for (j = kp1; j < N; j++) + { + double * col_j = a[j]; + temp = col_j[l]; + + if (l != k) + { + col_j[l] = col_j[k]; + col_j[k] = temp; + } + + daxpy(N - kp1, temp, col_k, kp1, 1, col_j, kp1, 1); + } + } + } + + ipvt[N - 1] = N - 1; + } + + // Solves the double precision system a * x = b or trans(a) * x = b + // using the factors computed by dgeco or dgefa. + void dgesl(double ** a, int * ipvt, double * b) + { + double t; + int k, kb; + + // solve a * x = b. first solve l*y = b + for (k = 0; k < NM1; k++) + { + int l = ipvt[k]; + t = b[l]; + + if (l != k) + { + b[l] = b[k]; + b[k] = t; + } + + int kp1 = k + 1; + daxpy(N - kp1, t, a[k], kp1, 1, b, kp1, 1); + } + + // now solve u*x = y + for (kb = 0; kb < N; kb++) + { + k = N - (kb + 1); + b[k] /= a[k][k]; + t = -b[k]; + daxpy(k, t, a[k], 0, 1, b, 0, 1); + } + } + + int main(int argc, char ** argv) + { + int i; + + // do we have verbose output? + bool ga_testing = false; + + if (argc > 1) + { + for (i = 1; i < argc; ++i) + { + if (!strcmp(argv[1],"-ga")) + { + ga_testing = true; + break; + } + } + } + + double ** a = (double **)malloc(sizeof(double) * N); + + for (i = 0; i < N; ++i) + a[i] = (double *)malloc(sizeof(double) * NP1); + + double * b = (double *)malloc(sizeof(double) * N); + double * x = (double *)malloc(sizeof(double) * N); + int * ipvt = (int *)malloc(sizeof(int) * N); + + // calculate operations per timeInSeconds + double ops = (2.0 * ((double)N * N * N)) / 3.0 + 2.0 * ((double)N * N); + + // generate matrix + matgen(a,b); + + // get starting time + //struct timespec start, stop; + //clock_gettime(CLOCK_REALTIME,&start); + + // what we're timing + dgefa(a,ipvt); + dgesl(a,ipvt,b); + + // calculate run time + //clock_gettime(CLOCK_REALTIME,&stop); + double run_time = 0;//(stop.tv_sec - start.tv_sec) + (double)(stop.tv_nsec - start.tv_nsec) / 1000000000.0; + + // clean up + free(ipvt); + free(x); + free(b); + + for (i = 0; i < N; ++i) + free(a[i]); + + free(a); + + // report runtime + if (ga_testing) + fprintf(stdout,"%f",run_time); + else + fprintf(stdout,"\nlpbench (Std. C) run time: %f\n\n",run_time); + + fflush(stdout); + + // done + return 0; + } From lattner at cs.uiuc.edu Sat Mar 4 16:36:21 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 16:36:21 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Makefile Message-ID: <200603042236.QAA06391@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks: Makefile updated: 1.4 -> 1.5 --- Log message: add coyote bench --- Diffs of the changes: (+2 -1) Makefile | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm-test/SingleSource/Benchmarks/Makefile diff -u llvm-test/SingleSource/Benchmarks/Makefile:1.4 llvm-test/SingleSource/Benchmarks/Makefile:1.5 --- llvm-test/SingleSource/Benchmarks/Makefile:1.4 Wed Oct 6 09:37:16 2004 +++ llvm-test/SingleSource/Benchmarks/Makefile Sat Mar 4 16:36:09 2006 @@ -1,5 +1,6 @@ LEVEL = ../.. -PARALLEL_DIRS=Dhrystone Shootout Shootout-C++ Stanford McGill Misc Misc-C++ +PARALLEL_DIRS=Dhrystone CoyoteBench Shootout Shootout-C++ Stanford McGill \ + Misc Misc-C++ LDFLAGS += -lm include $(LEVEL)/SingleSource/Makefile.singlesrc From lattner at cs.uiuc.edu Sat Mar 4 17:13:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 17:13:16 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Misc-C++-EH/ Message-ID: <200603042313.RAA06740@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/Misc-C++-EH: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm-test/SingleSource/Benchmarks/Misc-C++-EH added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Sat Mar 4 17:14:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Mar 2006 17:14:57 -0600 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Misc-C++-EH/Makefile spirit.cpp Message-ID: <200603042314.RAA06863@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/Misc-C++-EH: Makefile added (r1.1) spirit.cpp added (r1.1) --- Log message: Add a new benchmark: a boost spirit based C parser. --- Diffs of the changes: (+16845 -0) Makefile | 6 spirit.cpp |16839 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 16845 insertions(+) Index: llvm-test/SingleSource/Benchmarks/Misc-C++-EH/Makefile diff -c /dev/null llvm-test/SingleSource/Benchmarks/Misc-C++-EH/Makefile:1.1 *** /dev/null Sat Mar 4 17:14:55 2006 --- llvm-test/SingleSource/Benchmarks/Misc-C++-EH/Makefile Sat Mar 4 17:14:45 2006 *************** *** 0 **** --- 1,6 ---- + LEVEL = ../../.. + LDFLAGS += -lm -lstdc++ + LIBS = -lstdc++ + REQUIRES_EH_SUPPORT = 1 + + include $(LEVEL)/SingleSource/Makefile.singlesrc Index: llvm-test/SingleSource/Benchmarks/Misc-C++-EH/spirit.cpp diff -c /dev/null llvm-test/SingleSource/Benchmarks/Misc-C++-EH/spirit.cpp:1.1 *** /dev/null Sat Mar 4 17:14:57 2006 --- llvm-test/SingleSource/Benchmarks/Misc-C++-EH/spirit.cpp Sat Mar 4 17:14:45 2006 *************** *** 0 **** --- 1,16839 ---- + #include + #include + #include + #include + namespace boost { namespace spirit + { + struct nil_t {}; + }} + namespace boost { + namespace mpl { + namespace aux { + template< typename F > struct template_arity; + } + } + } + namespace boost { namespace mpl { + template< bool C_ > struct bool_; + typedef bool_ true_; + typedef bool_ false_; + }} + namespace boost { namespace mpl { + template< bool C_ > struct bool_ + { + static const bool value = C_; + typedef bool_ type; + typedef bool value_type; + operator bool() const { return this->value; } + }; + template< bool C_ > + bool const bool_::value; + }} + namespace boost { + template< typename T > struct is_integral : mpl::bool_< false > { }; + template<> struct is_integral< unsigned char > : mpl::bool_< true > { }; template<> struct is_integral< unsigned char const > : mpl::bool_< true > { }; template<> struct is_integral< unsigned char volatile > : mpl::bool_< true > { }; template<> struct is_integral< unsigned char const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< unsigned short > : mpl::bool_< true > { }; template<> struct is_integral< unsigned short const > : mpl::bool_< true > { }; template<> struct is_integral< unsigned short volatile > : mpl::bool_< true > { }; template<> struct is_integral< unsigned short const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< unsigned int > : mpl::bool_< true > { }; template<> struct is_integral< unsigned int const > : mpl::bool_< true > { }; template<> struct is_integral< unsigned int volatile > : mpl::bool_< true > { }; template<> struct is_integral< unsigned int const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< unsigned long > : mpl::bool_< true > { }; template<> struct is_integral< unsigned long const > : mpl::bool_< true > { }; template<> struct is_integral< unsigned long volatile > : mpl::bool_< true > { }; template<> struct is_integral< unsigned long const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< signed char > : mpl::bool_< true > { }; template<> struct is_integral< signed char const > : mpl::bool_< true > { }; template<> struct is_integral< signed char volatile > : mpl::bool_< true > { }; template<> struct is_integral< signed char const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< signed short > : mpl::bool_< true > { }; template<> struct is_integral< signed short const > : mpl::bool_< true > { }; template<> struct is_integral< signed short volatile > : mpl::bool_< true > { }; template<> struct is_integral< signed short const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< signed int > : mpl::bool_< true > { }; template<> struct is_integral< signed int const > : mpl::bool_< true > { }; template<> struct is_integral< signed int volatile > : mpl::bool_< true > { }; template<> struct is_integral< signed int const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< signed long > : mpl::bool_< true > { }; template<> struct is_integral< signed long const > : mpl::bool_< true > { }; template<> struct is_integral< signed long volatile > : mpl::bool_< true > { }; template<> struct is_integral< signed long const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< bool > : mpl::bool_< true > { }; template<> struct is_integral< bool const > : mpl::bool_< true > { }; template<> struct is_integral< bool volatile > : mpl::bool_< true > { }; template<> struct is_integral< bool const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< char > : mpl::bool_< true > { }; template<> struct is_integral< char const > : mpl::bool_< true > { }; template<> struct is_integral< char volatile > : mpl::bool_< true > { }; template<> struct is_integral< char const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< wchar_t > : mpl::bool_< true > { }; template<> struct is_integral< wchar_t const > : mpl::bool_< true > { }; template<> struct is_integral< wchar_t volatile > : mpl::bool_< true > { }; template<> struct is_integral< wchar_t const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< unsigned long long > : mpl::bool_< true > { }; template<> struct is_integral< unsigned long long const > : mpl::bool_< true > { }; template<> struct is_integral< unsigned long long volatile > : mpl::bool_< true > { }; template<> struct is_integral< unsigned long long const volatile > : mpl::bool_< true > { }; + template<> struct is_integral< long long > : mpl::bool_< true > { }; template<> struct is_integral< long long const > : mpl::bool_< true > { }; template<> struct is_integral< long long volatile > : mpl::bool_< true > { }; template<> struct is_integral< long long const volatile > : mpl::bool_< true > { }; + } + namespace boost { + template< typename T > struct is_float : mpl::bool_< false > { }; + template<> struct is_float< float > : mpl::bool_< true > { }; template<> struct is_float< float const > : mpl::bool_< true > { }; template<> struct is_float< float volatile > : mpl::bool_< true > { }; template<> struct is_float< float const volatile > : mpl::bool_< true > { }; + template<> struct is_float< double > : mpl::bool_< true > { }; template<> struct is_float< double const > : mpl::bool_< true > { }; template<> struct is_float< double volatile > : mpl::bool_< true > { }; template<> struct is_float< double const volatile > : mpl::bool_< true > { }; + template<> struct is_float< long double > : mpl::bool_< true > { }; template<> struct is_float< long double const > : mpl::bool_< true > { }; template<> struct is_float< long double volatile > : mpl::bool_< true > { }; template<> struct is_float< long double const volatile > : mpl::bool_< true > { }; + } + namespace boost { + namespace type_traits { + template + struct ice_or; + template + struct ice_or + { + static const bool value = true; + }; + template <> + struct ice_or + { + static const bool value = false; + }; + } + } + namespace boost { + namespace detail { + template< typename T > + struct is_arithmetic_impl + { + static const bool value = (::boost::type_traits::ice_or< ::boost::is_integral::value, ::boost::is_float::value >::value); + }; + } + template< typename T > struct is_arithmetic : mpl::bool_< ::boost::detail::is_arithmetic_impl::value > { }; + } + namespace boost { + template< typename T > struct is_void : mpl::bool_< false > { }; + template<> struct is_void< void > : mpl::bool_< true > { }; + template<> struct is_void< void const > : mpl::bool_< true > { }; + template<> struct is_void< void volatile > : mpl::bool_< true > { }; + template<> struct is_void< void const volatile > : mpl::bool_< true > { }; + } + namespace boost { + namespace detail { + template + struct is_fundamental_impl + : ::boost::type_traits::ice_or< + ::boost::is_arithmetic::value + , ::boost::is_void::value + > + { + }; + } + template< typename T > struct is_fundamental : mpl::bool_< ::boost::detail::is_fundamental_impl::value > { }; + } + namespace boost { + template< typename T > struct is_array : mpl::bool_< false > { }; + template< typename T, std::size_t N > struct is_array< T[N] > : mpl::bool_< true > { }; + template< typename T, std::size_t N > struct is_array< T const[N] > : mpl::bool_< true > { }; + template< typename T, std::size_t N > struct is_array< T volatile[N] > : mpl::bool_< true > { }; + template< typename T, std::size_t N > struct is_array< T const volatile[N] > : mpl::bool_< true > { }; + } + namespace boost { + template< typename T > struct is_reference : mpl::bool_< false > { }; + template< typename T > struct is_reference< T& > : mpl::bool_< true > { }; + } + namespace boost { + namespace detail { + template + struct add_reference_impl + { + typedef T& type; + }; + template< typename T > struct add_reference_impl { typedef T& type; }; + template<> struct add_reference_impl { typedef void type; }; + template<> struct add_reference_impl { typedef void const type; }; + template<> struct add_reference_impl { typedef void volatile type; }; + template<> struct add_reference_impl { typedef void const volatile type; }; + } + template< typename T > struct add_reference { typedef typename detail::add_reference_impl::type type; }; + } + namespace boost { + namespace type_traits { + typedef char yes_type; + struct no_type + { + char padding[8]; + }; + } + } + namespace boost { + namespace type_traits { + template + struct ice_and; + template + struct ice_and + { + static const bool value = false; + }; + template <> + struct ice_and + { + static const bool value = true; + }; + } + } + namespace boost { + namespace type_traits { + template + struct ice_not + { + static const bool value = true; + }; + template <> + struct ice_not + { + static const bool value = false; + }; + } + } + namespace boost { + namespace type_traits { + template + struct ice_eq + { + static const bool value = (b1 == b2); + }; + template + struct ice_ne + { + static const bool value = (b1 != b2); + }; + template bool const ice_eq::value; + template bool const ice_ne::value; + } + } + namespace boost { + namespace detail { + struct any_conversion + { + template any_conversion(const volatile T&); + template any_conversion(T&); + }; + template struct checker + { + static boost::type_traits::no_type _m_check(any_conversion ...); + static boost::type_traits::yes_type _m_check(T, int); + }; + template + struct is_convertible_basic_impl + { + static From _m_from; + static bool const value = sizeof( detail::checker::_m_check(_m_from, 0) ) + == sizeof(::boost::type_traits::yes_type); + }; + template + struct is_convertible_impl + { + typedef typename add_reference::type ref_type; + static const bool value = (::boost::type_traits::ice_and< ::boost::detail::is_convertible_basic_impl::value, ::boost::type_traits::ice_not< ::boost::is_array::value >::value >::value); + }; + template<> struct is_convertible_impl< void,void > { static const bool value = (true); }; template<> struct is_convertible_impl< void,void const > { static const bool value = (true); }; template<> struct is_convertible_impl< void,void volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void,void const volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void const,void > { static const bool value = (true); }; template<> struct is_convertible_impl< void const,void const > { static const bool value = (true); }; template<> struct is_convertible_impl< void const,void volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void const,void const volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void volatile,void > { static const bool value = (true); }; template<> struct is_convertible_impl< void volatile,void const > { static const! bool value = (true); }; template<> struct is_convertible_impl< void volatile,void volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void volatile,void const volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void const volatile,void > { static const bool value = (true); }; template<> struct is_convertible_impl< void const volatile,void const > { static const bool value = (true); }; template<> struct is_convertible_impl< void const volatile,void volatile > { static const bool value = (true); }; template<> struct is_convertible_impl< void const volatile,void const volatile > { static const bool value = (true); }; + template< typename To > struct is_convertible_impl< void,To > { static const bool value = (false); }; + template< typename From > struct is_convertible_impl< From,void > { static const bool value = (false); }; + template< typename To > struct is_convertible_impl< void const,To > { static const bool value = (false); }; + template< typename To > struct is_convertible_impl< void volatile,To > { static const bool value = (false); }; + template< typename To > struct is_convertible_impl< void const volatile,To > { static const bool value = (false); }; + template< typename From > struct is_convertible_impl< From,void const > { static const bool value = (false); }; + template< typename From > struct is_convertible_impl< From,void volatile > { static const bool value = (false); }; + template< typename From > struct is_convertible_impl< From,void const volatile > { static const bool value = (false); }; + } + template< typename From, typename To > struct is_convertible : mpl::bool_< (::boost::detail::is_convertible_impl::value) > { }; + template<> struct is_convertible< float,char > : mpl::bool_< true > { }; template<> struct is_convertible< float,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< float,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< float,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< float,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< float,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< float,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< float,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< float,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< float,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< float,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convertible< float const,char > : mpl::bool_< true > { }; template<> stru! ct is_convertible< float const,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< float const,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< float const,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< float const,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< float const,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< float const,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< float const,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< float const,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< float const,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< float const,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,char > : mpl::bool_< true > { }; template<> struct is_convertible< float v! olatile,signed char > : mpl::bool_< true > { }; template<> struct is_c onvertible< float volatile,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< float volatile,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,char > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,signed char > : mpl::bool_< true > { }; templat! e<> struct is_convertible< float const volatile,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< float const volatile,unsigned long long > : mpl::bool_< true > { }; + template<> struct is_convertible< double,char > : mpl::bool_< true > { }; template<> struct is_convertible< double,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< double,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< double,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< double,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< double,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< double,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< double,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< double,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< double,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< double,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convertible< double const,char > : mpl::bool_< true > { }; tem! plate<> struct is_convertible< double const,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< double const,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< double const,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< double const,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< double const,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< double const,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< double const,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< double const,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< double const,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< double const,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,char > : mpl::bool_< true > { }; template<> struct ! is_convertible< double volatile,signed char > : mpl::bool_< true > { } ; template<> struct is_convertible< double volatile,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< double volatile,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,char > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,signed char ! > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< double const volatile,unsigned long long > : mpl::bool_< true > { }; + template<> struct is_convertible< long double,char > : mpl::bool_< true > { }; template<> struct is_convertible< long double,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< long double,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< long double,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< long double,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< long double,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< long double,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< long double,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< long double,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< long double,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< long double,unsigned long long > : mpl::bool_< true > { }; template<> struct is_convert! ible< long double const,char > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< long double const,unsigned long long > : mpl::bool_< tru! e > { }; template<> struct is_convertible< long double volatile,char > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,signed long long > : mpl::bool_< true > { }; template<> struct is_convertible< long double volatile,unsigned long long > : mpl::bool_< true! > { }; template<> struct is_convertible< long double const volatile,char > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,signed char > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,unsigned char > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,signed short > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,unsigned short > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,signed int > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,unsigned int > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,signed long > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,unsigned long > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,signed lo! ng long > : mpl::bool_< true > { }; template<> struct is_convertible< long double const volatile,unsigned long long > : mpl::bool_< true > { }; + } + namespace boost { + namespace type_traits { + struct false_result + { + template struct result_ + { + static const bool value = false; + }; + }; + }} + namespace boost { + namespace type_traits { + template + struct is_function_ptr_helper + { + static const bool value = false; + }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + template + struct is_function_ptr_helper { static const bool value = true; }; + } + } + namespace boost { + namespace detail { + template + struct is_function_chooser + : ::boost::type_traits::false_result + { + }; + template <> + struct is_function_chooser + { + template< typename T > struct result_ + : ::boost::type_traits::is_function_ptr_helper + { + }; + }; + template + struct is_function_impl + : is_function_chooser< ::boost::is_reference::value > + ::template result_ + { + }; + } + template< typename T > struct is_function : mpl::bool_< ::boost::detail::is_function_impl::value > { }; + } + namespace boost { + namespace detail { + template struct cv_traits_imp {}; + template + struct cv_traits_imp + { + static const bool is_const = false; + static const bool is_volatile = false; + typedef T unqualified_type; + }; + template + struct cv_traits_imp + { + static const bool is_const = true; + static const bool is_volatile = false; + typedef T unqualified_type; + }; + template + struct cv_traits_imp + { + static const bool is_const = false; + static const bool is_volatile = true; + typedef T unqualified_type; + }; + template + struct cv_traits_imp + { + static const bool is_const = true; + static const bool is_volatile = true; + typedef T unqualified_type; + }; + } + } + namespace boost { + template< typename T > struct remove_cv { typedef typename detail::cv_traits_imp::unqualified_type type; }; + template< typename T > struct remove_cv { typedef T& type; }; + template< typename T, std::size_t N > struct remove_cv { typedef T type[N]; }; + template< typename T, std::size_t N > struct remove_cv { typedef T type[N]; }; + template< typename T, std::size_t N > struct remove_cv { typedef T type[N]; }; + } + namespace boost { + namespace detail { + template struct is_union_impl + { + static const bool value = false; + }; + } + template< typename T > struct is_union : mpl::bool_< ::boost::detail::is_union_impl::value > { }; + } + namespace boost { + namespace detail { + template ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); + template ::boost::type_traits::no_type is_class_tester(...); + template + struct is_class_impl + { + static const bool value = (::boost::type_traits::ice_and< sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type), ::boost::type_traits::ice_not< ::boost::is_union::value >::value >::value); + }; + } + template< typename T > struct is_class : mpl::bool_< ::boost::detail::is_class_impl::value > { }; + } + namespace boost { + namespace detail { + template + struct is_class_or_union + { + static const bool value = (::boost::type_traits::ice_or< ::boost::is_class::value , ::boost::is_union::value >::value); + }; + struct int_convertible + { + int_convertible(int); + }; + template + struct is_enum_helper + { + template struct type + { + static const bool value = false; + }; + }; + template <> + struct is_enum_helper + { + template struct type + : ::boost::is_convertible + { + }; + }; + template struct is_enum_impl + { + typedef ::boost::add_reference ar_t; + typedef typename ar_t::type r_type; + static const bool selector = (::boost::type_traits::ice_or< ::boost::is_arithmetic::value , ::boost::is_reference::value , ::boost::is_function::value , is_class_or_union::value >::value); + typedef ::boost::detail::is_enum_helper se_t; + typedef typename se_t::template type helper; + static const bool value = helper::value; + }; + template<> struct is_enum_impl< void > { static const bool value = (false); }; + template<> struct is_enum_impl< void const > { static const bool value = (false); }; + template<> struct is_enum_impl< void volatile > { static const bool value = (false); }; + template<> struct is_enum_impl< void const volatile > { static const bool value = (false); }; + } + template< typename T > struct is_enum : mpl::bool_< ::boost::detail::is_enum_impl::value > { }; + } + namespace boost { + namespace type_traits { + template + struct is_mem_fun_pointer_impl + { + static const bool value = false; + }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + template + struct is_mem_fun_pointer_impl { static const bool value = true; }; + } + } + namespace boost { + template< typename T > struct is_member_function_pointer : mpl::bool_< ::boost::type_traits::is_mem_fun_pointer_impl::value > { }; + } + namespace boost { + template< typename T > struct is_member_pointer : mpl::bool_< ::boost::is_member_function_pointer::value > { }; + template< typename T, typename U > struct is_member_pointer< U T::* > : mpl::bool_< true > { }; + } + namespace boost { + namespace detail { + template< typename T > struct is_pointer_helper + { + static const bool value = false; + }; + template< typename T > struct is_pointer_helper { static const bool value = true; }; + template< typename T > struct is_pointer_helper { static const bool value = true; }; + template< typename T > struct is_pointer_helper { static const bool value = true; }; + template< typename T > struct is_pointer_helper { static const bool value = true; }; + template< typename T > + struct is_pointer_impl + { + static const bool value = (::boost::type_traits::ice_and< ::boost::detail::is_pointer_helper::value , ::boost::type_traits::ice_not< ::boost::is_member_pointer::value >::value >::value); + }; + } + template< typename T > struct is_pointer : mpl::bool_< ::boost::detail::is_pointer_impl::value > { }; + } + namespace boost{ + namespace detail{ + template + struct ct_imp2 + { + typedef const T& param_type; + }; + template + struct ct_imp2 + { + typedef const T param_type; + }; + template + struct ct_imp + { + typedef const T& param_type; + }; + template + struct ct_imp + { + typedef typename ct_imp2::param_type param_type; + }; + template + struct ct_imp + { + typedef T const param_type; + }; + } + template + struct call_traits + { + public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef typename detail::ct_imp< + T, + ::boost::is_pointer::value, + ::boost::is_arithmetic::value + >::param_type param_type; + }; + template + struct call_traits + { + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; + }; + template + struct call_traits + { + private: + typedef T array_type[N]; + public: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; + }; + template + struct call_traits + { + private: + typedef const T array_type[N]; + public: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; + }; + } + #include + namespace boost { + template + struct type {}; + } + namespace boost { namespace mpl { + template< std::size_t N > struct size_t; + }} + namespace boost { namespace mpl { + template< std::size_t N > + struct size_t + { + static const std::size_t value = N; + typedef size_t type; + typedef std::size_t value_type; + typedef mpl::size_t< static_cast((value + 1)) > next; + typedef mpl::size_t< static_cast((value - 1)) > prior; + operator std::size_t() const { return static_cast(this->value); } + }; + template< std::size_t N > + std::size_t const mpl::size_t< N >::value; + }} + namespace boost { + template struct alignment_of; + namespace detail { + template + struct alignment_of_hack + { + char c; + T t; + alignment_of_hack(); + }; + template + struct alignment_logic + { + static const std::size_t value = A < S ? A : S; + }; + template< typename T > + struct alignment_of_impl + { + static const std::size_t value = (::boost::detail::alignment_logic< sizeof(detail::alignment_of_hack) - sizeof(T), sizeof(T) >::value); + }; + } + template< typename T > struct alignment_of : mpl::size_t< ::boost::detail::alignment_of_impl::value > { }; + template + struct alignment_of + : alignment_of + { + }; + template<> struct alignment_of : mpl::size_t< 0 > { }; + template<> struct alignment_of : mpl::size_t< 0 > { }; + template<> struct alignment_of : mpl::size_t< 0 > { }; + template<> struct alignment_of : mpl::size_t< 0 > { }; + } + namespace boost { + namespace mpl { + struct void_; + } + } + namespace boost { + namespace mpl { + struct void_ { typedef void_ type; }; + template< typename T > + struct is_void_ + : false_ + { + }; + template<> + struct is_void_ + : true_ + { + }; + } + } + namespace boost { + namespace mpl { + template< + typename T + , typename Tag + , typename Arity + > + struct lambda; + } + } + namespace boost { namespace mpl { + template< int N > struct int_; + }} + namespace boost { + namespace mpl { + template< int N > struct arg; + } + } + namespace boost { + namespace mpl { + namespace algo_ { + template< + bool C + , typename T1 + , typename T2 + > + struct if_c + { + typedef T1 type; + }; + template< + typename T1 + , typename T2 + > + struct if_c + { + typedef T2 type; + }; + template< + typename C = void_ + , typename T1 = void_ + , typename T2 = void_ + > + struct if_ + { + private: + typedef if_c< + static_cast(C::value) + , T1 + , T2 + > almost_type_; + public: + typedef typename almost_type_::type type; + + }; + } using namespace algo_; + namespace algo_ { template<> struct if_< void_,void_,void_ > { template< typename T1,typename T2,typename T3 , typename T4 =void_ ,typename T5 =void_ > struct apply : if_< T1,T2,T3 > { }; }; } using namespace algo_; template<> struct lambda< algo_:: if_< void_,void_,void_ > , void_ , int_<-1> > { typedef algo_:: if_< void_,void_,void_ > type; }; namespace aux { template< typename T1,typename T2,typename T3 > struct template_arity< algo_:: if_< T1,T2,T3 > > { static const int value = 3; }; template<> struct template_arity< algo_:: if_< void_,void_,void_ > > { static const int value = -1; }; } + template struct bind3; + template