OpenASIP 2.2
Loading...
Searching...
No Matches
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) {}
const TTAMachine::Machine & 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());
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}
#define __func__
#define assert(condition)
unsigned osalInputIndex(const Operation &operation, const llvm::MachineInstr &instr, unsigned operandId)
#define sub
static std::ostream & errorStream()
static int verboseLevel()
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
static bool supportsOperation(const TTAMachine::Machine &mach, TCEString operation)
virtual bool isInput() const
Definition Operand.cc:145
virtual int width() const
Definition Operand.cc:318
virtual bool isNull() const
Definition Operand.hh:130
Operation & operation(const char *name)
virtual bool readsMemory() const
Definition Operation.cc:242
virtual bool isCall() const
Definition Operation.cc:318
bool isNull() const
virtual bool isBranch() const
Definition Operation.cc:306
virtual Operand & operand(int id) const
Definition Operation.cc:541
virtual unsigned rvHighDRegNum()=0
virtual unsigned opcode(TCEString operationName) const =0
Returns the opcode for the given osal operation, undefined if not found.
std::string operationName(unsigned opc) const
virtual TCETargetMachinePlugin & targetPlugin() const

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: