//===-- X86FixupBWInsts.cpp - Fixup Byte or Word instructions -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file defines the pass that looks through the machine instructions /// late in the compilation, and finds byte or word instructions that /// can be profitably replaced with 32 bit instructions that give equivalent /// results for the bits of the results that are used. There are two possible /// reasons to do this. /// /// One reason is to avoid false-dependences on the upper portions /// of the registers. Only instructions that have a destination register /// which is not in any of the source registers can be affected by this. /// Any instruction where one of the source registers is also the destination /// register is unaffected, because it has a true dependence on the source /// register already. So, this consideration primarily affects load /// instructions and register-to-register moves. It would /// seem like cmov(s) would also be affected, but because of the way cmov is /// really implemented by most machines as reading both the destination and /// and source registers, and then "merging" the two based on a condition, /// it really already should be considered as having a true dependence on the /// destination register as well. /// /// The other reason to do this is for potential code size savings. Word /// operations need an extra override byte compared to their 32 bit /// versions. So this can convert many word operations to their larger /// size, saving a byte in encoding. This could introduce partial register /// dependences where none existed however. As an example take: /// orw ax, $0x1000 /// addw ax, $3 /// now if this were to get transformed into /// orw ax, $1000 /// addl eax, $3 /// because the addl encodes shorter than the addw, this would introduce /// a use of a register that was only partially written earlier. On older /// Intel processors this can be quite a performance penalty, so this should /// probably only be done when it can be proven that a new partial dependence /// wouldn't be created, or when your know a newer processor is being /// targeted, or when optimizing for minimum code size. /// //===----------------------------------------------------------------------===// #include "X86.h" #include "X86InstrInfo.h" #include "X86Subtarget.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" #include "llvm/CodeGen/LiveRegUnits.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineSizeOpts.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" usingnamespacellvm; #define FIXUPBW_DESC … #define FIXUPBW_NAME … #define DEBUG_TYPE … // Option to allow this optimization pass to have fine-grained control. static cl::opt<bool> FixupBWInsts("fixup-byte-word-insts", cl::desc("Change byte and word instructions to larger sizes"), cl::init(true), cl::Hidden); namespace { class FixupBWInstPass : public MachineFunctionPass { … }; char FixupBWInstPass::ID = …; } INITIALIZE_PASS(…) FunctionPass *llvm::createX86FixupBWInsts() { … } bool FixupBWInstPass::runOnMachineFunction(MachineFunction &MF) { … } /// Check if after \p OrigMI the only portion of super register /// of the destination register of \p OrigMI that is alive is that /// destination register. /// /// If so, return that super register in \p SuperDestReg. Register FixupBWInstPass::getSuperRegDestIfDead(MachineInstr *OrigMI) const { … } MachineInstr *FixupBWInstPass::tryReplaceLoad(unsigned New32BitOpcode, MachineInstr *MI) const { … } MachineInstr *FixupBWInstPass::tryReplaceCopy(MachineInstr *MI) const { … } MachineInstr *FixupBWInstPass::tryReplaceExtend(unsigned New32BitOpcode, MachineInstr *MI) const { … } MachineInstr *FixupBWInstPass::tryReplaceInstr(MachineInstr *MI, MachineBasicBlock &MBB) const { … } void FixupBWInstPass::processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB) { … }