TargetInstrInfoImpl.cpp revision 75361b69f3f327842b9dad69fa7f28ae3b688412
1641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//===-- TargetInstrInfoImpl.cpp - Target Instruction Information ----------===//
2641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//
3641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//                     The LLVM Compiler Infrastructure
4641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//
5641055225092833197efe8e5bce01d50bcf1daaeChris Lattner// This file is distributed under the University of Illinois Open Source
6641055225092833197efe8e5bce01d50bcf1daaeChris Lattner// License. See LICENSE.TXT for details.
7641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//
8641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//===----------------------------------------------------------------------===//
9641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//
10641055225092833197efe8e5bce01d50bcf1daaeChris Lattner// This file implements the TargetInstrInfoImpl class, it just provides default
11641055225092833197efe8e5bce01d50bcf1daaeChris Lattner// implementations of various methods.
12641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//
13641055225092833197efe8e5bce01d50bcf1daaeChris Lattner//===----------------------------------------------------------------------===//
14641055225092833197efe8e5bce01d50bcf1daaeChris Lattner
15641055225092833197efe8e5bce01d50bcf1daaeChris Lattner#include "llvm/Target/TargetInstrInfo.h"
16a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman#include "llvm/Target/TargetMachine.h"
17a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman#include "llvm/Target/TargetRegisterInfo.h"
1844eb65cf58e3ab9b5621ce72256d1621a18aeed7Owen Anderson#include "llvm/ADT/SmallVector.h"
19c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman#include "llvm/CodeGen/MachineFrameInfo.h"
20641055225092833197efe8e5bce01d50bcf1daaeChris Lattner#include "llvm/CodeGen/MachineInstr.h"
2158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h"
22c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman#include "llvm/CodeGen/MachineMemOperand.h"
23a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman#include "llvm/CodeGen/MachineRegisterInfo.h"
24c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman#include "llvm/CodeGen/PseudoSourceValue.h"
2534c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng#include "llvm/Support/ErrorHandling.h"
2634c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng#include "llvm/Support/raw_ostream.h"
27641055225092833197efe8e5bce01d50bcf1daaeChris Lattnerusing namespace llvm;
28641055225092833197efe8e5bce01d50bcf1daaeChris Lattner
29641055225092833197efe8e5bce01d50bcf1daaeChris Lattner// commuteInstruction - The default implementation of this method just exchanges
3034c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng// the two operands returned by findCommutedOpIndices.
3158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan ChengMachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI,
3258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng                                                      bool NewMI) const {
33498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  const TargetInstrDesc &TID = MI->getDesc();
34498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  bool HasDef = TID.getNumDefs();
3534c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng  if (HasDef && !MI->getOperand(0).isReg())
3634c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng    // No idea how to commute this instruction. Target should implement its own.
3734c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng    return 0;
3834c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng  unsigned Idx1, Idx2;
3934c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng  if (!findCommutedOpIndices(MI, Idx1, Idx2)) {
4034c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng    std::string msg;
4134c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng    raw_string_ostream Msg(msg);
4234c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng    Msg << "Don't know how to commute: " << *MI;
4375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error(Msg.str());
4434c75093f085c7958fa3bd31f3c4a50942d83505Evan Cheng  }
45498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng
46498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  assert(MI->getOperand(Idx1).isReg() && MI->getOperand(Idx2).isReg() &&
47641055225092833197efe8e5bce01d50bcf1daaeChris Lattner         "This only knows how to commute register operands so far");
48498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  unsigned Reg1 = MI->getOperand(Idx1).getReg();
49498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  unsigned Reg2 = MI->getOperand(Idx2).getReg();
50498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  bool Reg1IsKill = MI->getOperand(Idx1).isKill();
51498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  bool Reg2IsKill = MI->getOperand(Idx2).isKill();
5258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  bool ChangeReg0 = false;
53498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  if (HasDef && MI->getOperand(0).getReg() == Reg1) {
54a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng    // Must be two address instruction!
55a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng    assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
56a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng           "Expecting a two-address instruction!");
57a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng    Reg2IsKill = false;
5858dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    ChangeReg0 = true;
5958dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  }
6058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng
6158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  if (NewMI) {
6258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    // Create a new instruction.
63498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng    unsigned Reg0 = HasDef
64498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng      ? (ChangeReg0 ? Reg2 : MI->getOperand(0).getReg()) : 0;
65498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng    bool Reg0IsDead = HasDef ? MI->getOperand(0).isDead() : false;
668e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman    MachineFunction &MF = *MI->getParent()->getParent();
67498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng    if (HasDef)
68498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng      return BuildMI(MF, MI->getDebugLoc(), MI->getDesc())
69498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng        .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead))
70498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng        .addReg(Reg2, getKillRegState(Reg2IsKill))
71498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng        .addReg(Reg1, getKillRegState(Reg2IsKill));
72498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng    else
73498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng      return BuildMI(MF, MI->getDebugLoc(), MI->getDesc())
74498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng        .addReg(Reg2, getKillRegState(Reg2IsKill))
75498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng        .addReg(Reg1, getKillRegState(Reg2IsKill));
76a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng  }
7758dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng
7858dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  if (ChangeReg0)
7958dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    MI->getOperand(0).setReg(Reg2);
80498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  MI->getOperand(Idx2).setReg(Reg1);
81498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  MI->getOperand(Idx1).setReg(Reg2);
82498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  MI->getOperand(Idx2).setIsKill(Reg1IsKill);
83498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  MI->getOperand(Idx1).setIsKill(Reg2IsKill);
84641055225092833197efe8e5bce01d50bcf1daaeChris Lattner  return MI;
85641055225092833197efe8e5bce01d50bcf1daaeChris Lattner}
86641055225092833197efe8e5bce01d50bcf1daaeChris Lattner
87261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng/// findCommutedOpIndices - If specified MI is commutable, return the two
88261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng/// operand indices that would swap value. Return true if the instruction
89261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng/// is not in a form which this routine understands.
90261ce1d5f89155d2e6f914f281db2004c89ee839Evan Chengbool TargetInstrInfoImpl::findCommutedOpIndices(MachineInstr *MI,
91261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng                                                unsigned &SrcOpIdx1,
92261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng                                                unsigned &SrcOpIdx2) const {
93498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng  const TargetInstrDesc &TID = MI->getDesc();
94261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  if (!TID.isCommutable())
95498c2903e28b56b73b8056335ad7f1eb6347b8edEvan Cheng    return false;
96261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  // This assumes v0 = op v1, v2 and commuting would swap v1 and v2. If this
97261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  // is not true, then the target must implement this.
98261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  SrcOpIdx1 = TID.getNumDefs();
99261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  SrcOpIdx2 = SrcOpIdx1 + 1;
100261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  if (!MI->getOperand(SrcOpIdx1).isReg() ||
101261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng      !MI->getOperand(SrcOpIdx2).isReg())
102261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng    // No idea.
103261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng    return false;
104261ce1d5f89155d2e6f914f281db2004c89ee839Evan Cheng  return true;
105f20db159541bf27f5d2fdf8d4ba1c8b270b936dfEvan Cheng}
106f20db159541bf27f5d2fdf8d4ba1c8b270b936dfEvan Cheng
107f20db159541bf27f5d2fdf8d4ba1c8b270b936dfEvan Cheng
108641055225092833197efe8e5bce01d50bcf1daaeChris Lattnerbool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI,
10944eb65cf58e3ab9b5621ce72256d1621a18aeed7Owen Anderson                            const SmallVectorImpl<MachineOperand> &Pred) const {
110641055225092833197efe8e5bce01d50bcf1daaeChris Lattner  bool MadeChange = false;
111749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  const TargetInstrDesc &TID = MI->getDesc();
112749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  if (!TID.isPredicable())
113749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner    return false;
114749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner
115749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) {
116749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner    if (TID.OpInfo[i].isPredicate()) {
117749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner      MachineOperand &MO = MI->getOperand(i);
118d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      if (MO.isReg()) {
119749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner        MO.setReg(Pred[j].getReg());
120749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner        MadeChange = true;
121d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      } else if (MO.isImm()) {
122749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner        MO.setImm(Pred[j].getImm());
123749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner        MadeChange = true;
124d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      } else if (MO.isMBB()) {
125749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner        MO.setMBB(Pred[j].getMBB());
126749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner        MadeChange = true;
127641055225092833197efe8e5bce01d50bcf1daaeChris Lattner      }
128749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner      ++j;
129641055225092833197efe8e5bce01d50bcf1daaeChris Lattner    }
130641055225092833197efe8e5bce01d50bcf1daaeChris Lattner  }
131641055225092833197efe8e5bce01d50bcf1daaeChris Lattner  return MadeChange;
132641055225092833197efe8e5bce01d50bcf1daaeChris Lattner}
133ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Cheng
134ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Chengvoid TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
135ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Cheng                                        MachineBasicBlock::iterator I,
136ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Cheng                                        unsigned DestReg,
137378445303b10b092a898a75131141a8259cff50bEvan Cheng                                        unsigned SubIdx,
138d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng                                        const MachineInstr *Orig,
139d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng                                        const TargetRegisterInfo *TRI) const {
1408e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
141378445303b10b092a898a75131141a8259cff50bEvan Cheng  MachineOperand &MO = MI->getOperand(0);
142d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng  if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
143d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng    MO.setReg(DestReg);
144d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng    MO.setSubReg(SubIdx);
14539aa7251a27735479305b3e7a9629b9c2a6abcc3Evan Cheng  } else if (SubIdx) {
146d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng    MO.setReg(TRI->getSubReg(DestReg, SubIdx));
14739aa7251a27735479305b3e7a9629b9c2a6abcc3Evan Cheng  } else {
14839aa7251a27735479305b3e7a9629b9c2a6abcc3Evan Cheng    MO.setReg(DestReg);
149d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng  }
150ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Cheng  MBB.insert(I, MI);
151ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Cheng}
152ca1267c02b025cc719190b05f9e1a5d174a9caf7Evan Cheng
153506049f29f4f202a8e45feb916cc0264440a7f6dEvan Chengbool TargetInstrInfoImpl::produceSameValue(const MachineInstr *MI0,
154506049f29f4f202a8e45feb916cc0264440a7f6dEvan Cheng                                           const MachineInstr *MI1) const {
155506049f29f4f202a8e45feb916cc0264440a7f6dEvan Cheng  return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
156506049f29f4f202a8e45feb916cc0264440a7f6dEvan Cheng}
157506049f29f4f202a8e45feb916cc0264440a7f6dEvan Cheng
15830ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund OlesenMachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *Orig,
15930ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen                                             MachineFunction &MF) const {
16030ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  assert(!Orig->getDesc().isNotDuplicable() &&
16130ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen         "Instruction cannot be duplicated");
16230ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  return MF.CloneMachineInstr(Orig);
16330ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen}
16430ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen
16552e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffrayunsigned
16652e724ad7e679ee590f4bd763d55280586a8f1bcNicolas GeoffrayTargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
16752e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  unsigned FnSize = 0;
16852e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
16952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray       MBBI != E; ++MBBI) {
17052e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray    const MachineBasicBlock &MBB = *MBBI;
1713885578a36072dd55c3381b99d4a88299dddbfa3Evan Cheng    for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end();
1723885578a36072dd55c3381b99d4a88299dddbfa3Evan Cheng         I != E; ++I)
17352e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray      FnSize += GetInstSizeInBytes(I);
17452e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  }
17552e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  return FnSize;
17652e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray}
177c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
178c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// foldMemoryOperand - Attempt to fold a load or store of the specified stack
179c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// slot into the specified machine instruction for the specified operand(s).
180c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// If this is possible, a new instruction is returned with the specified
181c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// operand folded, otherwise NULL is returned. The client is responsible for
182c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// removing the old instruction and adding the new one in the instruction
183c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// stream.
184c54baa2d43730f1804acfb4f4e738fba72f966bdDan GohmanMachineInstr*
185c54baa2d43730f1804acfb4f4e738fba72f966bdDan GohmanTargetInstrInfo::foldMemoryOperand(MachineFunction &MF,
186c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman                                   MachineInstr* MI,
187c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman                                   const SmallVectorImpl<unsigned> &Ops,
188c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman                                   int FrameIndex) const {
189c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  unsigned Flags = 0;
190c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  for (unsigned i = 0, e = Ops.size(); i != e; ++i)
191c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman    if (MI->getOperand(Ops[i]).isDef())
192c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman      Flags |= MachineMemOperand::MOStore;
193c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman    else
194c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman      Flags |= MachineMemOperand::MOLoad;
195c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
196c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  // Ask the target to do the actual folding.
197c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, FrameIndex);
198c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  if (!NewMI) return 0;
199c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
200c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  assert((!(Flags & MachineMemOperand::MOStore) ||
201c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman          NewMI->getDesc().mayStore()) &&
202c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman         "Folded a def to a non-store!");
203c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  assert((!(Flags & MachineMemOperand::MOLoad) ||
204c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman          NewMI->getDesc().mayLoad()) &&
205c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman         "Folded a use to a non-load!");
206c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  const MachineFrameInfo &MFI = *MF.getFrameInfo();
207c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  assert(MFI.getObjectOffset(FrameIndex) != -1);
208c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman  MachineMemOperand *MMO =
209ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng    MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FrameIndex),
210c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman                            Flags, /*Offset=*/0,
211c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman                            MFI.getObjectSize(FrameIndex),
212c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman                            MFI.getObjectAlignment(FrameIndex));
213c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  NewMI->addMemOperand(MF, MMO);
214c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
215c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  return NewMI;
216c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman}
217c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
218c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// foldMemoryOperand - Same as the previous version except it allows folding
219c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// of any load and store from / to any address, not just from a specific
220c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman/// stack slot.
221c54baa2d43730f1804acfb4f4e738fba72f966bdDan GohmanMachineInstr*
222c54baa2d43730f1804acfb4f4e738fba72f966bdDan GohmanTargetInstrInfo::foldMemoryOperand(MachineFunction &MF,
223c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman                                   MachineInstr* MI,
224c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman                                   const SmallVectorImpl<unsigned> &Ops,
225c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman                                   MachineInstr* LoadMI) const {
226c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  assert(LoadMI->getDesc().canFoldAsLoad() && "LoadMI isn't foldable!");
227c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman#ifndef NDEBUG
228c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  for (unsigned i = 0, e = Ops.size(); i != e; ++i)
229c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman    assert(MI->getOperand(Ops[i]).isUse() && "Folding load into def!");
230c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman#endif
231c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
232c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  // Ask the target to do the actual folding.
233c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI);
234c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  if (!NewMI) return 0;
235c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
236c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  // Copy the memoperands from the load to the folded instruction.
237c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman  NewMI->setMemRefs(LoadMI->memoperands_begin(),
238c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman                    LoadMI->memoperands_end());
239c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman
240c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman  return NewMI;
241c54baa2d43730f1804acfb4f4e738fba72f966bdDan Gohman}
242a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
243a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohmanbool
244a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan GohmanTargetInstrInfo::isReallyTriviallyReMaterializableGeneric(const MachineInstr *
245a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman                                                            MI,
246a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman                                                          AliasAnalysis *
247a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman                                                            AA) const {
248a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  const MachineFunction &MF = *MI->getParent()->getParent();
249a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  const MachineRegisterInfo &MRI = MF.getRegInfo();
250a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  const TargetMachine &TM = MF.getTarget();
251a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  const TargetInstrInfo &TII = *TM.getInstrInfo();
252a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
253a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
254a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // A load from a fixed stack slot can be rematerialized. This may be
255a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // redundant with subsequent checks, but it's target-independent,
256a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // simple, and a common case.
257a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  int FrameIdx = 0;
258a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  if (TII.isLoadFromStackSlot(MI, FrameIdx) &&
259a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      MF.getFrameInfo()->isImmutableObjectIndex(FrameIdx))
260a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    return true;
261a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
262a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  const TargetInstrDesc &TID = MI->getDesc();
263a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
264a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // Avoid instructions obviously unsafe for remat.
265a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  if (TID.hasUnmodeledSideEffects() || TID.isNotDuplicable() ||
266a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      TID.mayStore())
267a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    return false;
268a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
269a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // Avoid instructions which load from potentially varying memory.
270a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  if (TID.mayLoad() && !MI->isInvariantLoad(AA))
271a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    return false;
272a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
273a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // If any of the registers accessed are non-constant, conservatively assume
274a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // the instruction is not rematerializable.
275a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
276a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    const MachineOperand &MO = MI->getOperand(i);
277a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    if (!MO.isReg()) continue;
278a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    unsigned Reg = MO.getReg();
279a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    if (Reg == 0)
280a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      continue;
281a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
282a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    // Check for a well-behaved physical register.
283a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
284a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      if (MO.isUse()) {
285a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        // If the physreg has no defs anywhere, it's just an ambient register
286a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        // and we can freely move its uses. Alternatively, if it's allocatable,
287a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        // it could get allocated to something with a def during allocation.
288a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        if (!MRI.def_empty(Reg))
289a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman          return false;
290a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        BitVector AllocatableRegs = TRI.getAllocatableSet(MF, 0);
291a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        if (AllocatableRegs.test(Reg))
292a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman          return false;
293a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        // Check for a def among the register's aliases too.
294a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        for (const unsigned *Alias = TRI.getAliasSet(Reg); *Alias; ++Alias) {
295a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman          unsigned AliasReg = *Alias;
296a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman          if (!MRI.def_empty(AliasReg))
297a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman            return false;
298a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman          if (AllocatableRegs.test(AliasReg))
299a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman            return false;
300a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        }
301a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      } else {
302a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        // A physreg def. We can't remat it.
303a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman        return false;
304a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      }
305a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      continue;
306a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    }
307a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
308a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    // Only allow one virtual-register def, and that in the first operand.
309a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    if (MO.isDef() != (i == 0))
310a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      return false;
311a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
312a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    // For the def, it should be the only def of that register.
3137896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner    if (MO.isDef() && (llvm::next(MRI.def_begin(Reg)) != MRI.def_end() ||
314a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman                       MRI.isLiveIn(Reg)))
315a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      return false;
316a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
317a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    // Don't allow any virtual-register uses. Rematting an instruction with
318a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    // virtual register uses would length the live ranges of the uses, which
319a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    // is not necessarily a good idea, certainly not "trivial".
320a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman    if (MO.isUse())
321a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman      return false;
322a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  }
323a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman
324a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  // Everything checked out.
325a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman  return true;
326a70dca156fa76d452f54829b5c5f962ddfd94ef2Dan Gohman}
327