Index: llvm/include/llvm/CodeGen/Passes.h =================================================================== --- llvm/include/llvm/CodeGen/Passes.h +++ llvm/include/llvm/CodeGen/Passes.h @@ -535,7 +535,7 @@ FunctionPass *createPseudoProbeInserter(); /// Create IR Type Promotion pass. \see TypePromotion.cpp - FunctionPass *createTypePromotionPass(); + FunctionPass *createTypePromotionLegacyPass(); /// Add Flow Sensitive Discriminators. PassNum specifies the /// sequence number of this pass (starting from 1). Index: llvm/include/llvm/CodeGen/TypePromotion.h =================================================================== --- /dev/null +++ llvm/include/llvm/CodeGen/TypePromotion.h @@ -0,0 +1,35 @@ +//===- TypePromotion.h ------------------------------------------*- C++ -*-===// +// +// 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 +/// +/// Defines an IR pass for type promotion. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_TYPEPROMOTION_H +#define LLVM_CODEGEN_TYPEPROMOTION_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class Function; +class TargetMachine; + +class TypePromotionPass : public PassInfoMixin { +private: + const TargetMachine *TM; + +public: + TypePromotionPass(const TargetMachine *TM): TM(TM) { } + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + +} // end namespace llvm + +#endif // LLVM_CODEGEN_TYPEPROMOTION_H Index: llvm/include/llvm/InitializePasses.h =================================================================== --- llvm/include/llvm/InitializePasses.h +++ llvm/include/llvm/InitializePasses.h @@ -402,7 +402,7 @@ void initializeTLSVariableHoistLegacyPassPass(PassRegistry &); void initializeTwoAddressInstructionPassPass(PassRegistry&); void initializeTypeBasedAAWrapperPassPass(PassRegistry&); -void initializeTypePromotionPass(PassRegistry&); +void initializeTypePromotionLegacyPass(PassRegistry&); void initializeUniformityInfoWrapperPassPass(PassRegistry &); void initializeUnifyFunctionExitNodesLegacyPassPass(PassRegistry &); void initializeUnifyLoopExitsLegacyPassPass(PassRegistry &); Index: llvm/lib/CodeGen/CMakeLists.txt =================================================================== --- llvm/lib/CodeGen/CMakeLists.txt +++ llvm/lib/CodeGen/CMakeLists.txt @@ -230,8 +230,8 @@ TargetRegisterInfo.cpp TargetSchedule.cpp TargetSubtargetInfo.cpp - TypePromotion.cpp TwoAddressInstructionPass.cpp + TypePromotion.cpp UnreachableBlockElim.cpp ValueTypes.cpp VLIWMachineScheduler.cpp Index: llvm/lib/CodeGen/CodeGen.cpp =================================================================== --- llvm/lib/CodeGen/CodeGen.cpp +++ llvm/lib/CodeGen/CodeGen.cpp @@ -129,7 +129,7 @@ initializeTailDuplicatePass(Registry); initializeTargetPassConfigPass(Registry); initializeTwoAddressInstructionPassPass(Registry); - initializeTypePromotionPass(Registry); + initializeTypePromotionLegacyPass(Registry); initializeUnpackMachineBundlesPass(Registry); initializeUnreachableBlockElimLegacyPassPass(Registry); initializeUnreachableMachineBlockElimPass(Registry); Index: llvm/lib/CodeGen/TypePromotion.cpp =================================================================== --- llvm/lib/CodeGen/TypePromotion.cpp +++ llvm/lib/CodeGen/TypePromotion.cpp @@ -15,6 +15,7 @@ /// //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/TypePromotion.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/LoopInfo.h" @@ -133,7 +134,7 @@ void Mutate(); }; -class TypePromotion : public FunctionPass { +class TypePromotionImpl { unsigned TypeSize = 0; LLVMContext *Ctx = nullptr; unsigned RegisterBitWidth = 0; @@ -170,10 +171,16 @@ bool isLegalToPromote(Value *V); bool TryToPromote(Value *V, unsigned PromotedWidth, const LoopInfo &LI); +public: + bool run(Function &F, const TargetMachine *TM, + const TargetTransformInfo &TTI, const LoopInfo &LI); +}; + +class TypePromotionLegacy : public FunctionPass { public: static char ID; - TypePromotion() : FunctionPass(ID) {} + TypePromotionLegacy() : FunctionPass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); @@ -196,19 +203,19 @@ Opc == Instruction::SRem || Opc == Instruction::SExt; } -bool TypePromotion::EqualTypeSize(Value *V) { +bool TypePromotionImpl::EqualTypeSize(Value *V) { return V->getType()->getScalarSizeInBits() == TypeSize; } -bool TypePromotion::LessOrEqualTypeSize(Value *V) { +bool TypePromotionImpl::LessOrEqualTypeSize(Value *V) { return V->getType()->getScalarSizeInBits() <= TypeSize; } -bool TypePromotion::GreaterThanTypeSize(Value *V) { +bool TypePromotionImpl::GreaterThanTypeSize(Value *V) { return V->getType()->getScalarSizeInBits() > TypeSize; } -bool TypePromotion::LessThanTypeSize(Value *V) { +bool TypePromotionImpl::LessThanTypeSize(Value *V) { return V->getType()->getScalarSizeInBits() < TypeSize; } @@ -219,7 +226,7 @@ /// return values because we only accept ones that guarantee a zeroext ret val. /// Many arguments will have the zeroext attribute too, so those would be free /// too. -bool TypePromotion::isSource(Value *V) { +bool TypePromotionImpl::isSource(Value *V) { if (!isa(V->getType())) return false; @@ -240,7 +247,7 @@ /// Return true if V will require any promoted values to be truncated for the /// the IR to remain valid. We can't mutate the value type of these /// instructions. -bool TypePromotion::isSink(Value *V) { +bool TypePromotionImpl::isSink(Value *V) { // TODO The truncate also isn't actually necessary because we would already // proved that the data value is kept within the range of the original data // type. We currently remove any truncs inserted for handling zext sinks. @@ -266,7 +273,7 @@ } /// Return whether this instruction can safely wrap. -bool TypePromotion::isSafeWrap(Instruction *I) { +bool TypePromotionImpl::isSafeWrap(Instruction *I) { // We can support a potentially wrapping instruction (I) if: // - It is only used by an unsigned icmp. // - The icmp uses a constant. @@ -372,7 +379,7 @@ return false; } -bool TypePromotion::shouldPromote(Value *V) { +bool TypePromotionImpl::shouldPromote(Value *V) { if (!isa(V->getType()) || isSink(V)) return false; @@ -683,7 +690,7 @@ /// We disallow booleans to make life easier when dealing with icmps but allow /// any other integer that fits in a scalar register. Void types are accepted /// so we can handle switches. -bool TypePromotion::isSupportedType(Value *V) { +bool TypePromotionImpl::isSupportedType(Value *V) { Type *Ty = V->getType(); // Allow voids and pointers, these won't be promoted. @@ -701,7 +708,7 @@ /// Disallow casts other than zext and truncs and only allow calls if their /// return value is zeroext. We don't allow opcodes that can introduce sign /// bits. -bool TypePromotion::isSupportedValue(Value *V) { +bool TypePromotionImpl::isSupportedValue(Value *V) { if (auto *I = dyn_cast(V)) { switch (I->getOpcode()) { default: @@ -749,7 +756,7 @@ /// Check that the type of V would be promoted and that the original type is /// smaller than the targeted promoted type. Check that we're not trying to /// promote something larger than our base 'TypeSize' type. -bool TypePromotion::isLegalToPromote(Value *V) { +bool TypePromotionImpl::isLegalToPromote(Value *V) { auto *I = dyn_cast(V); if (!I) return true; @@ -764,7 +771,7 @@ return false; } -bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth, +bool TypePromotionImpl::TryToPromote(Value *V, unsigned PromotedWidth, const LoopInfo &LI) { Type *OrigTy = V->getType(); TypeSize = OrigTy->getPrimitiveSizeInBits().getFixedSize(); @@ -896,29 +903,23 @@ return true; } -bool TypePromotion::runOnFunction(Function &F) { - if (skipFunction(F) || DisablePromotion) +bool TypePromotionImpl::run(Function &F, const TargetMachine *TM, + const TargetTransformInfo &TTI, + const LoopInfo &LI) { + if (DisablePromotion) return false; LLVM_DEBUG(dbgs() << "IR Promotion: Running on " << F.getName() << "\n"); - auto *TPC = getAnalysisIfAvailable(); - if (!TPC) - return false; - AllVisited.clear(); SafeToPromote.clear(); SafeWrap.clear(); bool MadeChange = false; const DataLayout &DL = F.getParent()->getDataLayout(); - const TargetMachine &TM = TPC->getTM(); - const TargetSubtargetInfo *SubtargetInfo = TM.getSubtargetImpl(F); + const TargetSubtargetInfo *SubtargetInfo = TM->getSubtargetImpl(F); const TargetLowering *TLI = SubtargetInfo->getTargetLowering(); - const TargetTransformInfo &TII = - getAnalysis().getTTI(F); - const LoopInfo &LI = getAnalysis().getLoopInfo(); RegisterBitWidth = - TII.getRegisterBitWidth(TargetTransformInfo::RGK_Scalar).getFixedSize(); + TTI.getRegisterBitWidth(TargetTransformInfo::RGK_Scalar).getFixedSize(); Ctx = &F.getParent()->getContext(); // Return the preferred integer width of the instruction, or zero if we @@ -1002,9 +1003,46 @@ return MadeChange; } -INITIALIZE_PASS_BEGIN(TypePromotion, DEBUG_TYPE, PASS_NAME, false, false) -INITIALIZE_PASS_END(TypePromotion, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS_BEGIN(TypePromotionLegacy, DEBUG_TYPE, PASS_NAME, false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END(TypePromotionLegacy, DEBUG_TYPE, PASS_NAME, false, false) + +char TypePromotionLegacy::ID = 0; -char TypePromotion::ID = 0; +bool TypePromotionLegacy::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; -FunctionPass *llvm::createTypePromotionPass() { return new TypePromotion(); } + auto *TPC = getAnalysisIfAvailable(); + if (!TPC) + return false; + + auto *TM = &TPC->getTM(); + auto &TTI = getAnalysis().getTTI(F); + auto &LI = getAnalysis().getLoopInfo(); + + TypePromotionImpl TP; + return TP.run(F, TM, TTI, LI); +} + +FunctionPass *llvm::createTypePromotionLegacyPass() { + return new TypePromotionLegacy(); +} + +PreservedAnalyses TypePromotionPass::run(Function &F, + FunctionAnalysisManager &AM) { + auto &TTI = AM.getResult(F); + auto &LI = AM.getResult(F); + TypePromotionImpl TP; + + bool Changed = TP.run(F, TM, TTI, LI); + if (!Changed) + return PreservedAnalyses::all(); + + PreservedAnalyses PA; + PA.preserveSet(); + PA.preserve(); + return PA; +} Index: llvm/lib/Passes/CMakeLists.txt =================================================================== --- llvm/lib/Passes/CMakeLists.txt +++ llvm/lib/Passes/CMakeLists.txt @@ -16,6 +16,7 @@ LINK_COMPONENTS AggressiveInstCombine Analysis + CodeGen Core Coroutines IPO Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -72,6 +72,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/Analysis/UniformityAnalysis.h" +#include "llvm/CodeGen/TypePromotion.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/PassManager.h" Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -384,6 +384,7 @@ FUNCTION_PASS("strip-gc-relocates", StripGCRelocates()) FUNCTION_PASS("structurizecfg", StructurizeCFGPass()) FUNCTION_PASS("tailcallelim", TailCallElimPass()) +FUNCTION_PASS("typepromotion", TypePromotionPass(TM)) FUNCTION_PASS("unify-loop-exits", UnifyLoopExitsPass()) FUNCTION_PASS("vector-combine", VectorCombinePass()) FUNCTION_PASS("verify", VerifierPass()) Index: llvm/lib/Target/AArch64/AArch64TargetMachine.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -648,7 +648,7 @@ void AArch64PassConfig::addCodeGenPrepare() { if (getOptLevel() != CodeGenOpt::None) - addPass(createTypePromotionPass()); + addPass(createTypePromotionLegacyPass()); TargetPassConfig::addCodeGenPrepare(); } Index: llvm/lib/Target/ARM/ARMTargetMachine.cpp =================================================================== --- llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -456,7 +456,7 @@ void ARMPassConfig::addCodeGenPrepare() { if (getOptLevel() != CodeGenOpt::None) - addPass(createTypePromotionPass()); + addPass(createTypePromotionLegacyPass()); TargetPassConfig::addCodeGenPrepare(); } Index: llvm/tools/opt/opt.cpp =================================================================== --- llvm/tools/opt/opt.cpp +++ llvm/tools/opt/opt.cpp @@ -450,7 +450,7 @@ initializeWasmEHPreparePass(Registry); initializeWriteBitcodePassPass(Registry); initializeHardwareLoopsPass(Registry); - initializeTypePromotionPass(Registry); + initializeTypePromotionLegacyPass(Registry); initializeReplaceWithVeclibLegacyPass(Registry); initializeJMCInstrumenterPass(Registry);