HexagonRemoveSZExtArgs.cpp revision 239462
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
15234285Sdim#include "HexagonTargetMachine.h"
16234285Sdim#include "llvm/Function.h"
17234285Sdim#include "llvm/Instructions.h"
18234285Sdim#include "llvm/Pass.h"
19234285Sdim#include "llvm/CodeGen/MachineFunctionAnalysis.h"
20234285Sdim#include "llvm/Transforms/Scalar.h"
21234285Sdim
22234285Sdimusing namespace llvm;
23234285Sdimnamespace {
24234285Sdim  struct HexagonRemoveExtendArgs : public FunctionPass {
25234285Sdim  public:
26234285Sdim    static char ID;
27234285Sdim    HexagonRemoveExtendArgs() : FunctionPass(ID) {}
28234285Sdim    virtual bool runOnFunction(Function &F);
29234285Sdim
30234285Sdim    const char *getPassName() const {
31234285Sdim      return "Remove sign extends";
32234285Sdim    }
33234285Sdim
34234285Sdim    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
35234285Sdim      AU.addRequired<MachineFunctionAnalysis>();
36234285Sdim      AU.addPreserved<MachineFunctionAnalysis>();
37234285Sdim      FunctionPass::getAnalysisUsage(AU);
38234285Sdim    }
39234285Sdim  };
40234285Sdim}
41234285Sdim
42234285Sdimchar HexagonRemoveExtendArgs::ID = 0;
43234285SdimRegisterPass<HexagonRemoveExtendArgs> X("reargs",
44234285Sdim                                        "Remove Sign and Zero Extends for Args"
45234285Sdim                                        );
46234285Sdim
47234285Sdim
48234285Sdim
49234285Sdimbool HexagonRemoveExtendArgs::runOnFunction(Function &F) {
50234285Sdim  unsigned Idx = 1;
51234285Sdim  for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE;
52234285Sdim       ++AI, ++Idx) {
53234285Sdim    if (F.paramHasAttr(Idx, Attribute::SExt)) {
54234285Sdim      Argument* Arg = AI;
55234285Sdim      if (!isa<PointerType>(Arg->getType())) {
56234285Sdim        for (Instruction::use_iterator UI = Arg->use_begin();
57234285Sdim             UI != Arg->use_end();) {
58234285Sdim          if (isa<SExtInst>(*UI)) {
59234285Sdim            Instruction* Use = cast<Instruction>(*UI);
60234285Sdim            SExtInst* SI = new SExtInst(Arg, Use->getType());
61234285Sdim            assert (EVT::getEVT(SI->getType()) ==
62234285Sdim                    (EVT::getEVT(Use->getType())));
63234285Sdim            ++UI;
64234285Sdim            Use->replaceAllUsesWith(SI);
65234285Sdim            Instruction* First = F.getEntryBlock().begin();
66234285Sdim            SI->insertBefore(First);
67234285Sdim            Use->eraseFromParent();
68234285Sdim          } else {
69234285Sdim            ++UI;
70234285Sdim          }
71234285Sdim        }
72234285Sdim      }
73234285Sdim    }
74234285Sdim  }
75234285Sdim  return true;
76234285Sdim}
77234285Sdim
78234285Sdim
79234285Sdim
80234285SdimFunctionPass *llvm::createHexagonRemoveExtendOps(HexagonTargetMachine &TM) {
81234285Sdim  return new HexagonRemoveExtendArgs();
82234285Sdim}
83