OpenASIP  2.0
Public Member Functions | Static Public Attributes | Private Attributes | List of all members
ConstantTransformer Class Reference

#include <ConstantTransformer.hh>

Inheritance diagram for ConstantTransformer:
Inheritance graph
Collaboration diagram for ConstantTransformer:
Collaboration graph

Public Member Functions

 ConstantTransformer (const TTAMachine::Machine &mach)
 
virtual ~ConstantTransformer ()
 
bool doInitialization (llvm::Module &M)
 
bool runOnMachineFunction (llvm::MachineFunction &mf)
 
bool doFinalization (llvm::Module &M)
 

Static Public Attributes

static char ID
 

Private Attributes

const TTAMachine::Machinemach_
 

Detailed Description

Transforms constants in the program that cannot be encoded by the machine to ones that can be.

Definition at line 43 of file ConstantTransformer.hh.

Constructor & Destructor Documentation

◆ ConstantTransformer()

ConstantTransformer::ConstantTransformer ( const TTAMachine::Machine mach)
inline

Definition at line 46 of file ConstantTransformer.hh.

47  :
48  MachineFunctionPass(ID), mach_(mach) {}

◆ ~ConstantTransformer()

virtual ConstantTransformer::~ConstantTransformer ( )
inlinevirtual

Definition at line 49 of file ConstantTransformer.hh.

49 {}

Member Function Documentation

◆ doFinalization()

bool ConstantTransformer::doFinalization ( llvm::Module &  M)

Definition at line 244 of file ConstantTransformer.cc.

244  {
245  return false;
246 }

◆ doInitialization()

bool ConstantTransformer::doInitialization ( llvm::Module &  M)

Definition at line 68 of file ConstantTransformer.cc.

68  {
69  return false;
70 }

◆ runOnMachineFunction()

bool ConstantTransformer::runOnMachineFunction ( llvm::MachineFunction &  mf)

Definition at line 113 of file ConstantTransformer.cc.

113  {
114 
115  const TCETargetMachine& tm =
116  dynamic_cast<const TCETargetMachine&>(mf.getTarget());
117  TCETargetMachinePlugin& plugin = tm.targetPlugin();
118 
119  OperationPool osal;
120 
121  bool changed = false;
122  for (MachineFunction::iterator i = mf.begin(); i != mf.end(); i++) {
123  MachineBasicBlock& mbb = *i;
124  for (MachineBasicBlock::iterator j = mbb.begin();
125  j != mbb.end(); j++) {
126  const llvm::MachineInstr* mi = &*j;
127  unsigned opc = mi->getOpcode();
128 
129  const llvm::MCInstrDesc& opDesc = mi->getDesc();
130  if (opDesc.isReturn()) {
131  continue;
132  }
133  if (opc == llvm::TargetOpcode::DBG_VALUE
134  || opc == llvm::TargetOpcode::DBG_LABEL
135  || opc == llvm::TargetOpcode::DBG_INSTR_REF
136  || opc == llvm::TargetOpcode::DBG_VALUE_LIST
137  || opc == llvm::TargetOpcode::DBG_PHI
138  || opc == llvm::TargetOpcode::KILL) {
139  continue;
140  }
141 
142  TCEString opname = tm.operationName(opc);
143  if (opname == "") continue;
144  bool hasGuard = opname[0] == '?' || opname[0] == '!';
145  if (hasGuard) opname = opname.substr(1);
146 
147  const Operation& op = osal.operation(opname.c_str());
148  if (op.isNull() || op.isBranch() || op.isCall() ||
149  op.readsMemory()) {
150  // isNull = INLINE asm, a pseudo asm block or similar.
151  // TODO: add support for at least INLINE and MOVE.
152 
153  // In case the operation reads memory, assume the
154  // possible immediate operand is a global address
155  // we cannot fix at this point.
156  // TODO: Fix global address constants. Needs to have new type
157  // of data symbol/relocation info in case an address
158  // constant is broken down.
159 
160  continue;
161  }
162 
163  for (unsigned operandI = 0; operandI < mi->getNumOperands();
164  ++operandI) {
165 
166  const MachineOperand& mo = mi->getOperand(operandI);
167  if (!mo.isImm()) continue;
168 
169  unsigned inputIndex = osalInputIndex(op, *mi, operandI);
170  if (inputIndex == 0) continue;
171  const Operand& operand = op.operand(inputIndex);
172  if (operand.isNull() || !operand.isInput()) {
173  continue; // ignore output operands
175  << "Input " << inputIndex
176  << " not found for operation "
177  << opname << std::endl;
178  assert(false);
179  }
180  assert(operand.isInput());
181  size_t operandWidth = operand.width();
182 
184  mach_, mo.getImm(), operandWidth)) continue;
185 
186  // check if it's possible to convert C to SUB(0, -C) such
187  // that it can be encoded for the target
190  mach_, -mo.getImm()) && /* SUB is 32b */
192 
193  const llvm::MCInstrInfo* iinfo =
194  mf.getTarget().getSubtargetImpl(
195  mf.getFunction())->getInstrInfo();
196  // RV_HIGH = SUB 0 -X
197  BuildMI(
198  mbb, j, j->getDebugLoc(), iinfo->get(plugin.opcode(sub)),
199  plugin.rvHighDRegNum()).addImm(0).addImm(-mo.getImm());
200 
201  // replace the original instruction's immediate operand
202  // with the RV_HIGH
203  llvm::MachineInstrBuilder mib =
204  BuildMI(mbb, j, j->getDebugLoc(), j->getDesc());
205  for (unsigned opr = 0; opr < j->getNumOperands(); ++opr) {
206  MachineOperand& orig = j->getOperand(opr);
207  if (opr == operandI) {
208  mib.add(MachineOperand::CreateReg(
209  plugin.rvHighDRegNum(), false));
210  continue;
211  }
212  mib.add(orig);
213  orig.clearParent();
214  }
215 
216  // the original instruction can be now deleted
217  j->eraseFromParent();
218  // start scanning the MBB from the beginning due to
219  // possibly invalidated iterators from adding the
220  // new instructions
221  j = mbb.begin();
222  changed = true;
223  } else {
224  std::ostringstream errMsg;
225  errMsg << "Program uses constant '"
226  << mo.getImm() << "'";
227  if (Application::verboseLevel() > 0) {
228  errMsg << " -> " << opname
229  << " (llvm opc = " << opc << ")";
230  }
231  errMsg << " that cannot be encoded "
232  << "for the machine by the current compiler.";
233  throw CompileError(
234  __FILE__, __LINE__, __func__, errMsg.str());
235  }
236  }
237  }
238 
239  }
240  return changed;
241 }

References __func__, assert, MachineInfo::canEncodeImmediateInteger(), Application::errorStream(), Operation::isBranch(), Operation::isCall(), Operand::isInput(), Operand::isNull(), Operation::isNull(), mach_, llvm::TCETargetMachinePlugin::opcode(), Operation::operand(), OperationPool::operation(), llvm::TCETargetMachine::operationName(), osalInputIndex(), Operation::readsMemory(), llvm::TCETargetMachinePlugin::rvHighDRegNum(), sub, MachineInfo::supportsOperation(), llvm::TCETargetMachine::targetPlugin(), Application::verboseLevel(), and Operand::width().

Here is the call graph for this function:

Member Data Documentation

◆ ID

char ConstantTransformer::ID
static

Definition at line 45 of file ConstantTransformer.hh.

◆ mach_

const TTAMachine::Machine& ConstantTransformer::mach_
private

Definition at line 56 of file ConstantTransformer.hh.

Referenced by runOnMachineFunction().


The documentation for this class was generated from the following files:
Operand
Definition: Operand.hh:52
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
MachineInfo::supportsOperation
static bool supportsOperation(const TTAMachine::Machine &mach, TCEString operation)
Definition: MachineInfo.cc:382
Operand::width
virtual int width() const
Definition: Operand.cc:318
CompileError
Definition: Exception.hh:1019
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
Operand::isNull
virtual bool isNull() const
Definition: Operand.hh:130
assert
#define assert(condition)
Definition: Application.hh:86
osalInputIndex
unsigned osalInputIndex(const Operation &operation, const llvm::MachineInstr &instr, unsigned operandId)
Definition: ConstantTransformer.cc:78
llvm::TCETargetMachinePlugin::opcode
virtual unsigned opcode(TCEString operationName) const =0
Returns the opcode for the given osal operation, undefined if not found.
__func__
#define __func__
Definition: Application.hh:67
Operation::readsMemory
virtual bool readsMemory() const
Definition: Operation.cc:242
Operation
Definition: Operation.hh:59
llvm::TCETargetMachinePlugin
Definition: TCETargetMachinePlugin.hh:109
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
llvm::TCETargetMachinePlugin::rvHighDRegNum
virtual unsigned rvHighDRegNum()=0
Application::errorStream
static std::ostream & errorStream()
Definition: Application.cc:171
Operation::isNull
bool isNull() const
TCEString
Definition: TCEString.hh:53
sub
#define sub
Definition: ConstantTransformer.cc:63
ConstantTransformer::mach_
const TTAMachine::Machine & mach_
Definition: ConstantTransformer.hh:56
ConstantTransformer::ID
static char ID
Definition: ConstantTransformer.hh:45
llvm::TCETargetMachine
Definition: TCETargetMachine.hh:106
Operation::isCall
virtual bool isCall() const
Definition: Operation.cc:318
OperationPool
Definition: OperationPool.hh:52
Operand::isInput
virtual bool isInput() const
Definition: Operand.cc:145
llvm::TCETargetMachine::operationName
std::string operationName(unsigned opc) const
Definition: TCETargetMachine.hh:188
Operation::isBranch
virtual bool isBranch() const
Definition: Operation.cc:306
MachineInfo::canEncodeImmediateInteger
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
Definition: MachineInfo.cc:444
llvm::TCETargetMachine::targetPlugin
virtual TCETargetMachinePlugin & targetPlugin() const
Definition: TCETargetMachine.hh:120