1b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//===-- FastISel.h - Definition of the FastISel class ---------------------===//
2b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//
3b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//                     The LLVM Compiler Infrastructure
4b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//
5b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// This file is distributed under the University of Illinois Open Source
6b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// License. See LICENSE.TXT for details.
7b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//
8b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//===----------------------------------------------------------------------===//
9b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//
10b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman// This file defines the FastISel class.
112ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson//
12b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman//===----------------------------------------------------------------------===//
132ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
14b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman#ifndef LLVM_CODEGEN_FASTISEL_H
15b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman#define LLVM_CODEGEN_FASTISEL_H
16b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
17b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman#include "llvm/ADT/DenseMap.h"
1884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman#include "llvm/CodeGen/MachineBasicBlock.h"
19255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/CodeGen/ValueTypes.h"
20b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
21b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmannamespace llvm {
22b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
230586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohmanclass AllocaInst;
24066b5d8403483bf3a8bb033b690da318fbc68e79Benjamin Kramerclass Constant;
2510df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohmanclass ConstantFP;
26a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohmanclass FunctionLoweringInfo;
27dd5b58ad7be78be90390074f0df138778af5c895Dan Gohmanclass Instruction;
28066b5d8403483bf3a8bb033b690da318fbc68e79Benjamin Kramerclass LoadInst;
29b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanclass MachineBasicBlock;
3095267a1e671efc3c14e916b6978bbb15973b4cdcOwen Andersonclass MachineConstantPool;
31b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanclass MachineFunction;
32f81eca0ab908fdcf98ae0efaa75acccc8ba40dc2Dan Gohmanclass MachineInstr;
330586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohmanclass MachineFrameInfo;
34bb466331e7e50d03497ce40ee344870236fd9c32Dan Gohmanclass MachineRegisterInfo;
353574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmowclass DataLayout;
36b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanclass TargetInstrInfo;
37d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilsonclass TargetLibraryInfo;
3883785c80968165b30fcdd111ceb2c28d38bcff86Evan Chengclass TargetLowering;
3922bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohmanclass TargetMachine;
40b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanclass TargetRegisterClass;
41db4971259ce94cea26e555e9ade82672a3581f5cDan Gohmanclass TargetRegisterInfo;
42066b5d8403483bf3a8bb033b690da318fbc68e79Benjamin Kramerclass User;
43066b5d8403483bf3a8bb033b690da318fbc68e79Benjamin Kramerclass Value;
44b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
4540610241d00e219341ff4b7106c5baff08ad407bDan Gohman/// FastISel - This is a fast-path instruction selection class that
4640610241d00e219341ff4b7106c5baff08ad407bDan Gohman/// generates poor code and doesn't support illegal types or non-trivial
4740610241d00e219341ff4b7106c5baff08ad407bDan Gohman/// lowering, but runs quickly.
48b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanclass FastISel {
4922bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohmanprotected:
50104e4ce1629ea84736691bd1ee7867bdf90e8a2eDan Gohman  DenseMap<const Value *, unsigned> LocalValueMap;
51a4160c3434b08288d1f79f1acbe453d1b9610b22Dan Gohman  FunctionLoweringInfo &FuncInfo;
52bb466331e7e50d03497ce40ee344870236fd9c32Dan Gohman  MachineRegisterInfo &MRI;
530586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman  MachineFrameInfo &MFI;
540586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman  MachineConstantPool &MCP;
559bc96a57206cbebaa9b0ba9979f949eb10c1592cBill Wendling  DebugLoc DL;
5622bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman  const TargetMachine &TM;
573574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  const DataLayout &TD;
58bb466331e7e50d03497ce40ee344870236fd9c32Dan Gohman  const TargetInstrInfo &TII;
5922bb31103de3337f0bb74c7bee16d1817d4dca14Dan Gohman  const TargetLowering &TLI;
60db4971259ce94cea26e555e9ade82672a3581f5cDan Gohman  const TargetRegisterInfo &TRI;
61d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson  const TargetLibraryInfo *LibInfo;
6274af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin
6374af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// The position of the last instruction for materializing constants
6474af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// for use in the current block. It resets to EmitStartPt when it
6574af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// makes sense (for example, it's usually profitable to avoid function
6674af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// calls between the definition and the use)
6784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  MachineInstr *LastLocalValue;
68b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
6974af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// The top most instruction in the current block that is allowed for
7074af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// emitting local variables. LastLocalValue resets to EmitStartPt when
7174af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// it makes sense (for example, on function calls)
7274af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  MachineInstr *EmitStartPt;
7374af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin
74b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanpublic:
7584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// getLastLocalValue - Return the position of the last instruction
7684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// emitted for materializing constants for use in the current block.
7784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  MachineInstr *getLastLocalValue() { return LastLocalValue; }
7884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman
7984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// setLastLocalValue - Update the position of the last instruction
8084023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// emitted for materializing constants for use in the current block.
8174af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  void setLastLocalValue(MachineInstr *I) {
8274af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin    EmitStartPt = I;
8374af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin    LastLocalValue = I;
8474af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  }
8584023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman
869bc96a57206cbebaa9b0ba9979f949eb10c1592cBill Wendling  /// startNewBlock - Set the current block to which generated machine
879bc96a57206cbebaa9b0ba9979f949eb10c1592cBill Wendling  /// instructions will be appended, and clear the local CSE map.
88241f464d24a6c22721607841069bbeb17b3f71e6Dan Gohman  ///
8984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  void startNewBlock();
90241f464d24a6c22721607841069bbeb17b3f71e6Dan Gohman
91390f3ace34855a3d4c9e0adf468976375f8c6dc1Devang Patel  /// getCurDebugLoc() - Return current debug location information.
92390f3ace34855a3d4c9e0adf468976375f8c6dc1Devang Patel  DebugLoc getCurDebugLoc() const { return DL; }
93092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
94092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  /// LowerArguments - Do "fast" instruction selection for function arguments
95092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  /// and append machine instructions to the current block. Return true if
96092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  /// it is successful.
97092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  bool LowerArguments();
98390f3ace34855a3d4c9e0adf468976375f8c6dc1Devang Patel
993df24e667f04a7003342b534310919abc9c87418Dan Gohman  /// SelectInstruction - Do "fast" instruction selection for the given
1003df24e667f04a7003342b534310919abc9c87418Dan Gohman  /// LLVM IR instruction, and append generated machine instructions to
1013df24e667f04a7003342b534310919abc9c87418Dan Gohman  /// the current block. Return true if selection was successful.
1023df24e667f04a7003342b534310919abc9c87418Dan Gohman  ///
10346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectInstruction(const Instruction *I);
104b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
105e2d0af4d7802a36e183897cc061747ba88819226Dan Gohman  /// SelectOperator - Do "fast" instruction selection for the given
10640b189e4e257924d90aaf63bf2e12bc7bbca961aDan Gohman  /// LLVM IR operator (Instruction or ConstantExpr), and append
10740b189e4e257924d90aaf63bf2e12bc7bbca961aDan Gohman  /// generated machine instructions to the current block. Return true
10840b189e4e257924d90aaf63bf2e12bc7bbca961aDan Gohman  /// if selection was successful.
10940b189e4e257924d90aaf63bf2e12bc7bbca961aDan Gohman  ///
11046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectOperator(const User *I, unsigned Opcode);
11140b189e4e257924d90aaf63bf2e12bc7bbca961aDan Gohman
1123df24e667f04a7003342b534310919abc9c87418Dan Gohman  /// getRegForValue - Create a virtual register and arrange for it to
1133df24e667f04a7003342b534310919abc9c87418Dan Gohman  /// be assigned the value for the given LLVM value.
11446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  unsigned getRegForValue(const Value *V);
11599b218218c0ca3ebfdd568ddfeafa07842e9d69dDan Gohman
11659fbc80f6b3b5c71dfb84149f589625f7ed510e3Evan Cheng  /// lookUpRegForValue - Look up the value to see if its value is already
11759fbc80f6b3b5c71dfb84149f589625f7ed510e3Evan Cheng  /// cached in a register. It may be defined by instructions across blocks or
11859fbc80f6b3b5c71dfb84149f589625f7ed510e3Evan Cheng  /// defined locally.
11946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  unsigned lookUpRegForValue(const Value *V);
12059fbc80f6b3b5c71dfb84149f589625f7ed510e3Evan Cheng
121c8a1a3c426209e9c7b35e279e1578a89edc40af6Dan Gohman  /// getRegForGEPIndex - This is a wrapper around getRegForValue that also
122c8a1a3c426209e9c7b35e279e1578a89edc40af6Dan Gohman  /// takes care of truncating or sign-extending the given getelementptr
123c8a1a3c426209e9c7b35e279e1578a89edc40af6Dan Gohman  /// index value.
124a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman  std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
125c8a1a3c426209e9c7b35e279e1578a89edc40af6Dan Gohman
126beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  /// TryToFoldLoad - The specified machine instr operand is a vreg, and that
127beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  /// vreg is being provided by the specified load instruction.  If possible,
128beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  /// try to fold the load as an operand to the instruction, returning true if
129beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  /// possible.
130beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  virtual bool TryToFoldLoad(MachineInstr * /*MI*/, unsigned /*OpNo*/,
131beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner                             const LoadInst * /*LI*/) {
132beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner    return false;
133beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  }
1342ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
135beac75da3784929aee9f0357fc5cd76d49d6c3d7Chris Lattner  /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions
13684023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// into the current block.
13784023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  void recomputeInsertPt();
13884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman
139425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier  /// removeDeadCode - Remove all dead instructions between the I and E.
140425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier  void removeDeadCode(MachineBasicBlock::iterator I,
141425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier                      MachineBasicBlock::iterator E);
142425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier
14376ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher  struct SavePoint {
14476ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher    MachineBasicBlock::iterator InsertPt;
14576ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher    DebugLoc DL;
14676ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher  };
14776ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher
14884023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// enterLocalValueArea - Prepare InsertPt to begin inserting instructions
14984023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman  /// into the local value area and return the old insert position.
15076ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher  SavePoint enterLocalValueArea();
15184023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman
152a10b8494a50108482302f6f077d72fbc76d776edDan Gohman  /// leaveLocalValueArea - Reset InsertPt to the given old insert position.
15376ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher  void leaveLocalValueArea(SavePoint Old);
15484023e0fbefc406a4c611d3d64a10df5d3a97dd7Dan Gohman
155cc8430f742b0f1e567292c8a776e94fc1c930b2aDan Gohman  virtual ~FastISel();
156cc8430f742b0f1e567292c8a776e94fc1c930b2aDan Gohman
157b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohmanprotected:
158d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson  explicit FastISel(FunctionLoweringInfo &funcInfo,
159d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson                    const TargetLibraryInfo *libInfo);
160e285a74f7cf9dd3ccf4fe758576cf83301f8a43eDan Gohman
1616e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman  /// TargetSelectInstruction - This method is called by target-independent
1626e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman  /// code when the normal FastISel process fails to select an instruction.
1636e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman  /// This gives targets a chance to emit code for anything that doesn't
1646e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman  /// fit into FastISel's framework. It returns true if it was successful.
1656e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman  ///
1666e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman  virtual bool
16746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  TargetSelectInstruction(const Instruction *I) = 0;
168092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
169092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  /// FastLowerArguments - This method is called by target-independent code to
170092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  /// do target specific argument lowering. It returns true if it was
171092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  /// successful.
172092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  virtual bool FastLowerArguments();
1736e3ff375474c4fd78feb0b8463eb273a23cb4404Dan Gohman
174bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// FastEmit_r - This method is called by target-independent code
175bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// to request that an instruction with the given type and opcode
176bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// be emitted.
177825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_(MVT VT,
178825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                             MVT RetVT,
1797c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                             unsigned Opcode);
180bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman
181bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// FastEmit_r - This method is called by target-independent code
182bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// to request that an instruction with the given type, opcode, and
183bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// register operand be emitted.
184bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  ///
185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_r(MVT VT,
186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                              MVT RetVT,
187a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                              unsigned Opcode,
188a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                              unsigned Op0, bool Op0IsKill);
189bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman
190bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// FastEmit_rr - This method is called by target-independent code
191bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// to request that an instruction with the given type, opcode, and
192bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// register operands be emitted.
193bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  ///
194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_rr(MVT VT,
195825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                               MVT RetVT,
1967c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                               unsigned Opcode,
197a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                               unsigned Op0, bool Op0IsKill,
198a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                               unsigned Op1, bool Op1IsKill);
199b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
20083785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// FastEmit_ri - This method is called by target-independent code
20183785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// to request that an instruction with the given type, opcode, and
20283785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// register and immediate operands be emitted.
20383785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  ///
204825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_ri(MVT VT,
205825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                               MVT RetVT,
2067c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                               unsigned Opcode,
207a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                               unsigned Op0, bool Op0IsKill,
208a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                               uint64_t Imm);
209d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman
21010df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// FastEmit_rf - This method is called by target-independent code
21110df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// to request that an instruction with the given type, opcode, and
21210df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// register and floating-point immediate operands be emitted.
21310df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  ///
214825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_rf(MVT VT,
215825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                               MVT RetVT,
2167c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                               unsigned Opcode,
217a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                               unsigned Op0, bool Op0IsKill,
218a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                               const ConstantFP *FPImm);
21910df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman
220d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// FastEmit_rri - This method is called by target-independent code
221d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// to request that an instruction with the given type, opcode, and
222d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// register and immediate operands be emitted.
223d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  ///
224825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_rri(MVT VT,
225825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                MVT RetVT,
2267c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                                unsigned Opcode,
227a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                                unsigned Op0, bool Op0IsKill,
228a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                                unsigned Op1, bool Op1IsKill,
229a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                                uint64_t Imm);
23083785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng
23183785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries
23283785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// to emit an instruction with an immediate operand using FastEmit_ri.
23383785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// If that fails, it materializes the immediate into a register and try
23483785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng  /// FastEmit_rr instead.
235825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  unsigned FastEmit_ri_(MVT VT,
2367c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                        unsigned Opcode,
237a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                        unsigned Op0, bool Op0IsKill,
238a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                        uint64_t Imm, MVT ImmType);
2392ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
2406d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson  /// FastEmit_i - This method is called by target-independent code
2416d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson  /// to request that an instruction with the given type, opcode, and
2426d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson  /// immediate operand be emitted.
243825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_i(MVT VT,
244825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                              MVT RetVT,
2457c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                              unsigned Opcode,
2466d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson                              uint64_t Imm);
24783785c80968165b30fcdd111ceb2c28d38bcff86Evan Cheng
24810df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// FastEmit_f - This method is called by target-independent code
24910df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// to request that an instruction with the given type, opcode, and
25010df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// floating-point immediate operand be emitted.
251825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  virtual unsigned FastEmit_f(MVT VT,
252825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                              MVT RetVT,
2537c3ecb6838ef7a2ca306c0f3cd68022f0855ae71Dan Gohman                              unsigned Opcode,
25446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman                              const ConstantFP *FPImm);
25510df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman
256bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// FastEmitInst_ - Emit a MachineInstr with no operands and a
257bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// result register in the given register class.
258bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  ///
259b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman  unsigned FastEmitInst_(unsigned MachineInstOpcode,
260b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman                         const TargetRegisterClass *RC);
261bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman
262d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// FastEmitInst_r - Emit a MachineInstr with one register operand
263bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// and a result register in the given register class.
264bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  ///
265b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman  unsigned FastEmitInst_r(unsigned MachineInstOpcode,
266b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman                          const TargetRegisterClass *RC,
267a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                          unsigned Op0, bool Op0IsKill);
268bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman
269d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// FastEmitInst_rr - Emit a MachineInstr with two register operands
270bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  /// and a result register in the given register class.
271bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman  ///
272b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman  unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
273b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman                           const TargetRegisterClass *RC,
274a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                           unsigned Op0, bool Op0IsKill,
275a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                           unsigned Op1, bool Op1IsKill);
276bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman
277d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson  /// FastEmitInst_rrr - Emit a MachineInstr with three register operands
278d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson  /// and a result register in the given register class.
279d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson  ///
280d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson  unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
281d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson                           const TargetRegisterClass *RC,
282d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson                           unsigned Op0, bool Op0IsKill,
283d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson                           unsigned Op1, bool Op1IsKill,
284d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson                           unsigned Op2, bool Op2IsKill);
285d71867a8f4b1ab6ab8cc8f5b1a732184ec5bad1bOwen Anderson
2863728b4ad8bfb42171cc04bb01bc95302fa66810bEric Christopher  /// FastEmitInst_ri - Emit a MachineInstr with a register operand,
2873728b4ad8bfb42171cc04bb01bc95302fa66810bEric Christopher  /// an immediate, and a result register in the given register class.
288d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  ///
289d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
290d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman                           const TargetRegisterClass *RC,
291a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                           unsigned Op0, bool Op0IsKill,
292a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                           uint64_t Imm);
293d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman
2942ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson  /// FastEmitInst_rii - Emit a MachineInstr with one register operand
2952ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson  /// and two immediate operands.
2962ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson  ///
2972ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson  unsigned FastEmitInst_rii(unsigned MachineInstOpcode,
2982ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson                           const TargetRegisterClass *RC,
2992ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson                           unsigned Op0, bool Op0IsKill,
3002ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson                           uint64_t Imm1, uint64_t Imm2);
3012ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
30210df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// FastEmitInst_rf - Emit a MachineInstr with two register operands
30310df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  /// and a result register in the given register class.
30410df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  ///
30510df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman  unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
30610df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman                           const TargetRegisterClass *RC,
307a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                           unsigned Op0, bool Op0IsKill,
308a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                           const ConstantFP *FPImm);
30910df0fa73e396bbc93a8940e8b53827390c54d10Dan Gohman
310d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// FastEmitInst_rri - Emit a MachineInstr with two register operands,
311d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  /// an immediate, and a result register in the given register class.
312d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  ///
313d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman  unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
314d5fe57d2f980c6bd1a61450f99c254a76d0f1683Dan Gohman                            const TargetRegisterClass *RC,
315a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                            unsigned Op0, bool Op0IsKill,
316a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                            unsigned Op1, bool Op1IsKill,
317a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                            uint64_t Imm);
3182ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
31968f25571e759c1fcf2da206109647259f49f7416Manman Ren  /// FastEmitInst_rrii - Emit a MachineInstr with two register operands,
32068f25571e759c1fcf2da206109647259f49f7416Manman Ren  /// two immediates operands, and a result register in the given register
32168f25571e759c1fcf2da206109647259f49f7416Manman Ren  /// class.
32268f25571e759c1fcf2da206109647259f49f7416Manman Ren  unsigned FastEmitInst_rrii(unsigned MachineInstOpcode,
32368f25571e759c1fcf2da206109647259f49f7416Manman Ren                             const TargetRegisterClass *RC,
32468f25571e759c1fcf2da206109647259f49f7416Manman Ren                             unsigned Op0, bool Op0IsKill,
32568f25571e759c1fcf2da206109647259f49f7416Manman Ren                             unsigned Op1, bool Op1IsKill,
32668f25571e759c1fcf2da206109647259f49f7416Manman Ren                             uint64_t Imm1, uint64_t Imm2);
32768f25571e759c1fcf2da206109647259f49f7416Manman Ren
3286d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson  /// FastEmitInst_i - Emit a MachineInstr with a single immediate
3296d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson  /// operand, and a result register in the given register class.
3306d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson  unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
3316d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson                          const TargetRegisterClass *RC,
3326d0c25ec3a7ca822e68f73a4481eee43eb5c9485Owen Anderson                          uint64_t Imm);
333d74ea775af55782e3b0d5b10fa7602f8822a2f72Owen Anderson
334d74ea775af55782e3b0d5b10fa7602f8822a2f72Owen Anderson  /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands.
335d74ea775af55782e3b0d5b10fa7602f8822a2f72Owen Anderson  unsigned FastEmitInst_ii(unsigned MachineInstrOpcode,
336d74ea775af55782e3b0d5b10fa7602f8822a2f72Owen Anderson                          const TargetRegisterClass *RC,
337d74ea775af55782e3b0d5b10fa7602f8822a2f72Owen Anderson                          uint64_t Imm1, uint64_t Imm2);
338d74ea775af55782e3b0d5b10fa7602f8822a2f72Owen Anderson
3398970f00deff00ffce1f35cf00883357e1582daa1Owen Anderson  /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg
340536ab130ec95cbb7bf30530251dafa7dfecc8471Evan Cheng  /// from a specified index of a superregister to a specified type.
341825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  unsigned FastEmitInst_extractsubreg(MVT RetVT,
342a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                                      unsigned Op0, bool Op0IsKill,
343a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                                      uint32_t Idx);
3448970f00deff00ffce1f35cf00883357e1582daa1Owen Anderson
34514ea1ec2324cb595f2e035bbf54ddcd483f17c11Dan Gohman  /// FastEmitZExtFromI1 - Emit MachineInstrs to compute the value of Op
34614ea1ec2324cb595f2e035bbf54ddcd483f17c11Dan Gohman  /// with all but the least significant bit set to zero.
347825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  unsigned FastEmitZExtFromI1(MVT VT,
348a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman                              unsigned Op0, bool Op0IsKill);
34914ea1ec2324cb595f2e035bbf54ddcd483f17c11Dan Gohman
350d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman  /// FastEmitBranch - Emit an unconditional branch to the given block,
351d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman  /// unless it is the immediate (fall-through) successor, and update
352d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman  /// the CFG.
3533bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings  void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL);
354d98d6203e429b2d7208b6687931e9079e85e95ecDan Gohman
355482feb33b2bba677d47bab859d9e1e95d67016bdEli Friedman  void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1);
356ea09f4f4691a0db65772b54fe8163a48c9dce01dEvan Cheng
357c7f72de3b4ef21828ea4780f0693bf0acd04e1c5Dan Gohman  unsigned createResultReg(const TargetRegisterClass *RC);
3582ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
3592ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson  /// TargetMaterializeConstant - Emit a constant in a register using
3609c7216f984111eb8f1716741bc9039ed86ec4a9bOwen Anderson  /// target-specific logic, such as constant pool loads.
36146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  virtual unsigned TargetMaterializeConstant(const Constant* C) {
3620586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman    return 0;
3630586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman  }
3640586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman
3650586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman  /// TargetMaterializeAlloca - Emit an alloca address in a register using
3660586d91bb3e516d5826826522d9a90ed6ef74d86Dan Gohman  /// target-specific logic.
36746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) {
36895267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson    return 0;
36995267a1e671efc3c14e916b6978bbb15973b4cdcOwen Anderson  }
370c7f72de3b4ef21828ea4780f0693bf0acd04e1c5Dan Gohman
3712790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman  virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) {
3722790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman    return 0;
3732790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman  }
3742790ba8e5a7bb6e00fdac9997d840598fb60271cEli Friedman
375ea09f4f4691a0db65772b54fe8163a48c9dce01dEvan Chengprivate:
37646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
377bdedd4477331b3b0d28d74658baf05f675f2d195Dan Gohman
37846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectFNeg(const User *I);
3793d45a853db014fdddcdb79424e663dfed5eccbc7Dan Gohman
38046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectGetElementPtr(const User *I);
381763d89343be210eb62a13318ca0cc9321ce46bfbDan Gohman
38246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectCall(const User *I);
38333134c4a75558288d663267c8991f6bd37a530afDan Gohman
38446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectBitCast(const User *I);
3852ce5bf188dfa4329eb246df6011dd1edde5a5979Owen Anderson
38646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  bool SelectCast(const User *I, unsigned Opcode);
387e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman
3882586b8f9366aed5a1efa44d3f18d095511601642Eli Friedman  bool SelectExtractValue(const User *I);
3892586b8f9366aed5a1efa44d3f18d095511601642Eli Friedman
390cd462d055ffc18a526a9a1d343261d8550e99280Chad Rosier  bool SelectInsertValue(const User *I);
391cd462d055ffc18a526a9a1d343261d8550e99280Chad Rosier
392e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
393e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  /// Emit code to ensure constants are copied into registers when needed.
394e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  /// Remember the virtual registers that need to be added to the Machine PHI
395e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  /// nodes as input.  We cannot just directly add them, because expansion
396e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  /// might result in multiple MBB's for one BB.  As such, the start of the
397e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  /// BB might correspond to a different MBB than the end.
398e8c92dd439581bec7e3516cbdbea74e2e60fe7f0Dan Gohman  bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
3991fdc614bee2a324fcc210d1e46d9b6fca3ca324bDan Gohman
4001fdc614bee2a324fcc210d1e46d9b6fca3ca324bDan Gohman  /// materializeRegForValue - Helper for getRegForVale. This function is
4011fdc614bee2a324fcc210d1e46d9b6fca3ca324bDan Gohman  /// called when the value isn't already available in a register and must
4021fdc614bee2a324fcc210d1e46d9b6fca3ca324bDan Gohman  /// be materialized with new instructions.
4031fdc614bee2a324fcc210d1e46d9b6fca3ca324bDan Gohman  unsigned materializeRegForValue(const Value *V, MVT VT);
404a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman
40574af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// flushLocalValueMap - clears LocalValueMap and moves the area for the
40674af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// new local variables to the beginning of the block. It helps to avoid
40774af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  /// spilling cached variables across heavy instructions like calls.
40874af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin  void flushLocalValueMap();
40974af88a6661ad5185924bf39164fb4aa144d32cfIvan Krasin
410a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman  /// hasTrivialKill - Test whether the given value has exactly one use.
411a6cb641f48df20f6f79018569b519e5a32e897a2Dan Gohman  bool hasTrivialKill(const Value *V) const;
412b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman};
413b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
414b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman}
415b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman
416b0cf29c5cfff797284b3660dc233e135feb65d9aDan Gohman#endif
417