1239462Sdim//===- HexagonRemoveExtendArgs.cpp - Remove unnecessary argument sign extends // 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// Pass that removes sign extends for function parameters. These parameters 11234285Sdim// are already sign extended by the caller per Hexagon's ABI 12234285Sdim// 13234285Sdim//===----------------------------------------------------------------------===// 14234285Sdim 15249423Sdim#include "Hexagon.h" 16234285Sdim#include "HexagonTargetMachine.h" 17249423Sdim#include "llvm/CodeGen/MachineFunctionAnalysis.h" 18249423Sdim#include "llvm/IR/Function.h" 19249423Sdim#include "llvm/IR/Instructions.h" 20234285Sdim#include "llvm/Pass.h" 21234285Sdim#include "llvm/Transforms/Scalar.h" 22234285Sdim 23234285Sdimusing namespace llvm; 24251662Sdim 25251662Sdimnamespace llvm { 26251662Sdim void initializeHexagonRemoveExtendArgsPass(PassRegistry&); 27251662Sdim} 28251662Sdim 29234285Sdimnamespace { 30234285Sdim struct HexagonRemoveExtendArgs : public FunctionPass { 31234285Sdim public: 32234285Sdim static char ID; 33251662Sdim HexagonRemoveExtendArgs() : FunctionPass(ID) { 34251662Sdim initializeHexagonRemoveExtendArgsPass(*PassRegistry::getPassRegistry()); 35251662Sdim } 36234285Sdim virtual bool runOnFunction(Function &F); 37234285Sdim 38234285Sdim const char *getPassName() const { 39234285Sdim return "Remove sign extends"; 40234285Sdim } 41234285Sdim 42234285Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const { 43234285Sdim AU.addRequired<MachineFunctionAnalysis>(); 44234285Sdim AU.addPreserved<MachineFunctionAnalysis>(); 45234285Sdim FunctionPass::getAnalysisUsage(AU); 46234285Sdim } 47234285Sdim }; 48234285Sdim} 49234285Sdim 50234285Sdimchar HexagonRemoveExtendArgs::ID = 0; 51234285Sdim 52251662SdimINITIALIZE_PASS(HexagonRemoveExtendArgs, "reargs", 53251662Sdim "Remove Sign and Zero Extends for Args", false, false) 54234285Sdim 55234285Sdimbool HexagonRemoveExtendArgs::runOnFunction(Function &F) { 56234285Sdim unsigned Idx = 1; 57234285Sdim for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE; 58234285Sdim ++AI, ++Idx) { 59249423Sdim if (F.getAttributes().hasAttribute(Idx, Attribute::SExt)) { 60234285Sdim Argument* Arg = AI; 61234285Sdim if (!isa<PointerType>(Arg->getType())) { 62234285Sdim for (Instruction::use_iterator UI = Arg->use_begin(); 63234285Sdim UI != Arg->use_end();) { 64234285Sdim if (isa<SExtInst>(*UI)) { 65234285Sdim Instruction* Use = cast<Instruction>(*UI); 66234285Sdim SExtInst* SI = new SExtInst(Arg, Use->getType()); 67234285Sdim assert (EVT::getEVT(SI->getType()) == 68234285Sdim (EVT::getEVT(Use->getType()))); 69234285Sdim ++UI; 70234285Sdim Use->replaceAllUsesWith(SI); 71234285Sdim Instruction* First = F.getEntryBlock().begin(); 72234285Sdim SI->insertBefore(First); 73234285Sdim Use->eraseFromParent(); 74234285Sdim } else { 75234285Sdim ++UI; 76234285Sdim } 77234285Sdim } 78234285Sdim } 79234285Sdim } 80234285Sdim } 81234285Sdim return true; 82234285Sdim} 83234285Sdim 84234285Sdim 85234285Sdim 86251662SdimFunctionPass* 87251662Sdimllvm::createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM) { 88234285Sdim return new HexagonRemoveExtendArgs(); 89234285Sdim} 90