protected void assertParamCount( int nParamsCount, String strFunctionName, List<Expression> listArgs) { if (listArgs.size() != nParamsCount) errors.SemErr( la.line, la.col, StringUtil.concat( strFunctionName, " expects ", nParamsCount, " parameters, but ", listArgs.size(), " were provided.")); }
@Override public String getLoopHeadAnnotation() { return StringUtil.concat( "for ", m_idLoopIndex, " = ", m_exprStart, "..", m_exprEnd, " by ", m_exprStep, " parallel ", m_exprNumThreads, " <level ", m_nParallelismLevel, "> schedule ", m_rgChunkSize == null ? "1" : m_rgChunkSize[0], " { ... }"); }
@Override public String toJavaCode(Map<IOperand, String> mapOperands) { StringBuilder sb = new StringBuilder(); StringBuilder sbInstr = new StringBuilder("il.addInstruction (new Instruction (\""); sbInstr.append(m_strInstructionName); sbInstr.append('"'); if (m_intrinsic != null) { sbInstr.append(", TypeBaseIntrinsicEnum."); sbInstr.append(m_intrinsic.value()); } for (IOperand op : m_rgOperands) { String strOp = mapOperands.get(op); if (strOp == null) { strOp = op.toJavaCode(); String[] strParts = strOp.split(" "); if (strParts[0].equals("new")) { String strOperand = StringUtil.concat("op", mapOperands.size()); sb.append(strParts[1]); sb.append(' '); sb.append(strOperand); sb.append(" = "); sb.append(strOp); sb.append(";\n"); strOp = strOperand; } mapOperands.put(op, strOp); } sbInstr.append(", "); sbInstr.append(strOp); } sbInstr.append("));"); sb.append(sbInstr); return sb.toString(); }
@Override public String toString() { return StringUtil.concat( "for ", m_idLoopIndex, " = ", m_exprStart, "..", m_exprEnd, " by ", m_exprStep, " parallel ", m_exprNumThreads, " <level ", m_nParallelismLevel, "> schedule ", m_rgChunkSize == null ? "1" : m_rgChunkSize[0], "\n", getLoopBody()); }
/** * Translates the generic instruction <code>instruction</code> into an architecture-specific one. * The generated instruction(s) are added to the <code>m_ilOut</code> instruction list. * * @param instruction The instruction to translate */ private void translateInstruction(Instruction instruction) { Intrinsic intrinsic = getIntrinsicForInstruction(instruction); if (intrinsic == null) { LOGGER.debug( StringUtil.concat( "No intrinsic found for the instruction ", instruction.getInstructionName())); m_ilOut.addInstruction(instruction); return; } // get the source operands, i.e., the instruction arguments IOperand[] rgSourceOps = instruction.getOperands(); IOperand opSourceOutput = rgSourceOps[rgSourceOps.length - 1]; // get the destination operands, i.e., the arguments of the architecture-specific intrinsic Argument[] rgDestArgs = null; if (intrinsic.getArguments() != null) rgDestArgs = Arguments.parseArguments(intrinsic.getArguments()); else { LOGGER.debug( StringUtil.concat( "No arguments were defined for the intrinsic ", intrinsic.getBaseName(), ". Assuming generic arguments.")); rgDestArgs = InstructionListTranslator.createGenericArguments(rgSourceOps.length); } // check whether the number of arguments of the instruction and the intrinsic to be generated // match // the source instruction always has a result operand (the last instruction argument); in the // intrinsic // the result might be merged into one of the operands, so there might be one argument less if (rgSourceOps.length != rgDestArgs.length && rgSourceOps.length - 1 != rgDestArgs.length) { LOGGER.error( StringUtil.concat( "The arguments for the instruction ", instruction.toString(), " mapped to the intrinsic ", intrinsic.getBaseName(), " don't match")); return; } boolean bIntrinsicHasSharedResult = rgSourceOps.length - 1 == rgDestArgs.length; int nOutputArgDestIndex = InstructionListTranslator.getOutputArgumentIndex(rgDestArgs); int[] rgPermSourceToDest = new int[rgSourceOps.length]; int[] rgPermDestToSource = new int[rgDestArgs.length]; InstructionListTranslator.getArgumentPermutations( intrinsic, rgSourceOps, rgDestArgs, rgPermSourceToDest, rgPermDestToSource); if (!bIntrinsicHasSharedResult) { // the intrinsic to generate has a distinct output operand // if possible, swap commutative operands if that helps saving MOVs rgSourceOps = InstructionListTranslator.compatibilizeCommutatives( intrinsic, rgSourceOps, rgDestArgs, rgPermSourceToDest, rgPermDestToSource, nOutputArgDestIndex, bIntrinsicHasSharedResult); } else { // the intrinsic to generate has an operand which is used for shared input and output, // i.e., upon completion of the instruction, the shared operand is overwritten with the result if (opSourceOutput.equals(rgSourceOps[rgPermDestToSource[nOutputArgDestIndex]])) { // the argument of the instruction corresponding to the shared intrinsic operand // is the same as the instruction's result argument } else { if (rgSourceOps[rgSourceOps.length - 1] instanceof IOperand.IRegisterOperand) { // if possible, swap commutative operands if that helps saving MOVs rgSourceOps = InstructionListTranslator.compatibilizeCommutatives( intrinsic, rgSourceOps, rgDestArgs, rgPermSourceToDest, rgPermDestToSource, nOutputArgDestIndex, bIntrinsicHasSharedResult); } } } createInstructions( instruction, intrinsic, rgSourceOps, rgDestArgs, rgPermSourceToDest, rgPermDestToSource, nOutputArgDestIndex, bIntrinsicHasSharedResult); }