@@ -566,32 +566,54 @@ bool DwarfExpression::addExpression(
566566 case dwarf::DW_OP_LLVM_extract_bits_zext: {
567567 unsigned SizeInBits = Op->getArg (1 );
568568 unsigned BitOffset = Op->getArg (0 );
569+ unsigned DerefSize = 0 ;
570+ // Operations are done in the DWARF "generic type" whose size
571+ // is the size of a pointer.
572+ unsigned PtrSizeInBytes = CU.getAsmPrinter ()->MAI ->getCodePointerSize ();
569573
570574 // If we have a memory location then dereference to get the value, though
571575 // we have to make sure we don't dereference any bytes past the end of the
572576 // object.
573577 if (isMemoryLocation ()) {
574- emitOp (dwarf::DW_OP_deref_size);
575- emitUnsigned (alignTo (BitOffset + SizeInBits, 8 ) / 8 );
578+ DerefSize = alignTo (BitOffset + SizeInBits, 8 ) / 8 ;
579+ if (DerefSize == PtrSizeInBytes) {
580+ emitOp (dwarf::DW_OP_deref);
581+ } else {
582+ emitOp (dwarf::DW_OP_deref_size);
583+ emitUnsigned (DerefSize);
584+ }
576585 }
577586
578- // Extract the bits by a shift left (to shift out the bits after what we
579- // want to extract) followed by shift right (to shift the bits to position
580- // 0 and also sign/zero extend). These operations are done in the DWARF
581- // "generic type" whose size is the size of a pointer.
582- unsigned PtrSizeInBytes = CU.getAsmPrinter ()->MAI ->getCodePointerSize ();
583- unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);
584- unsigned RightShift = LeftShift + BitOffset;
585- if (LeftShift) {
586- emitOp (dwarf::DW_OP_constu);
587- emitUnsigned (LeftShift);
588- emitOp (dwarf::DW_OP_shl);
589- }
590- if (RightShift) {
591- emitOp (dwarf::DW_OP_constu);
592- emitUnsigned (RightShift);
593- emitOp (OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra
594- : dwarf::DW_OP_shr);
587+ // If a dereference was emitted for an unsigned value, and
588+ // there's no bit offset, then a bit of optimization is
589+ // possible.
590+ if (OpNum == dwarf::DW_OP_LLVM_extract_bits_zext && BitOffset == 0 ) {
591+ if (8 * DerefSize == SizeInBits) {
592+ // The correct value is already on the stack.
593+ } else {
594+ // No need to shift, we can just mask off the desired bits.
595+ emitOp (dwarf::DW_OP_constu);
596+ emitUnsigned ((1u << SizeInBits) - 1 );
597+ emitOp (dwarf::DW_OP_and);
598+ }
599+ } else {
600+ // Extract the bits by a shift left (to shift out the bits after what we
601+ // want to extract) followed by shift right (to shift the bits to
602+ // position 0 and also sign/zero extend).
603+ unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);
604+ unsigned RightShift = LeftShift + BitOffset;
605+ if (LeftShift) {
606+ emitOp (dwarf::DW_OP_constu);
607+ emitUnsigned (LeftShift);
608+ emitOp (dwarf::DW_OP_shl);
609+ }
610+ if (RightShift) {
611+ emitOp (dwarf::DW_OP_constu);
612+ emitUnsigned (RightShift);
613+ emitOp (OpNum == dwarf::DW_OP_LLVM_extract_bits_sext
614+ ? dwarf::DW_OP_shra
615+ : dwarf::DW_OP_shr);
616+ }
595617 }
596618
597619 // The value is now at the top of the stack, so set the location to
0 commit comments