static void Scalarize(pTHX_ SV *sv, AV *av) { int n = av_len(av)+1; if (n == 0) sv_setpvn(sv,"",0); else { SV **svp; if (n == 1 && (svp = av_fetch(av, 0, 0))) { STRLEN len = 0; char *s = SvPV(*svp,len); #ifdef SvUTF8 int utf8 = SvUTF8(*svp); sv_setpvn(sv,s,len); if (utf8) SvUTF8_on(sv); #else sv_setpvn(sv,s,len); #endif } else { Tcl_DString ds; int i; Tcl_DStringInit(&ds); for (i=0; i < n; i++) { if ((svp = av_fetch(av, i, 0))) { SV *el = *svp; int temp = 0; if (SvROK(el) && !SvOBJECT(SvRV(el)) && SvTYPE(SvRV(el)) == SVt_PVAV) { el = newSVpv("",0); temp = 1; if ((AV *) SvRV(*svp) == av) abort(); Scalarize(aTHX_ el,(AV *) SvRV(*svp)); } Tcl_DStringAppendElement(&ds,Tcl_GetString(el)); if (temp) SvREFCNT_dec(el); } } sv_setpvn(sv,Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); sv_maybe_utf8(sv); Tcl_DStringFree(&ds); } } }
static SV * ForceScalar(pTHX_ SV *sv) { if (SvGMAGICAL(sv)) mg_get(sv); if (SvTYPE(sv) == SVt_PVAV) { AV *av = (AV *) sv; SV *newsv = newSVpv("",0); Scalarize(aTHX_ newsv, (AV *) av); av_clear(av); av_store(av,0,newsv); return newsv; } else { if (SvROK(sv) && !SvOBJECT(SvRV(sv)) && SvTYPE(SvRV(sv)) == SVt_PVAV) { /* Callbacks and lists often get stringified by mistake due to Tcl/Tk's string fixation - don't change the real value */ SV *newsv = newSVpv("",0); Scalarize(aTHX_ newsv, (AV *) SvRV(sv)); return sv_2mortal(newsv); } else if (!SvOK(sv)) { /* Map undef to null string */ if (SvREADONLY(sv)) { SV *newsv = newSVpv("",0); return sv_2mortal(newsv); } else sv_setpvn(sv,"",0); } return sv; } }
Value *BoUpSLP::vectorizeTree(ValueList &VL, int VF) { Type *ScalarTy = VL[0]->getType(); if (StoreInst *SI = dyn_cast<StoreInst>(VL[0])) ScalarTy = SI->getValueOperand()->getType(); VectorType *VecTy = VectorType::get(ScalarTy, VF); // Check if all of the operands are constants or identical. bool AllConst = true; bool AllSameScalar = true; for (unsigned i = 0, e = VF; i < e; ++i) { AllConst &= !!dyn_cast<Constant>(VL[i]); AllSameScalar &= (VL[0] == VL[i]); // Must have a single use. Instruction *I = dyn_cast<Instruction>(VL[i]); if (I && (I->getNumUses() > 1 || I->getParent() != BB)) return Scalarize(VL, VecTy); } // Is this a simple vector constant. if (AllConst || AllSameScalar) return Scalarize(VL, VecTy); // Scalarize unknown structures. Instruction *VL0 = dyn_cast<Instruction>(VL[0]); if (!VL0) return Scalarize(VL, VecTy); unsigned Opcode = VL0->getOpcode(); for (unsigned i = 0, e = VF; i < e; ++i) { Instruction *I = dyn_cast<Instruction>(VL[i]); // If not all of the instructions are identical then we have to scalarize. if (!I || Opcode != I->getOpcode()) return Scalarize(VL, VecTy); } switch (Opcode) { case Instruction::Add: case Instruction::FAdd: case Instruction::Sub: case Instruction::FSub: case Instruction::Mul: case Instruction::FMul: case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: case Instruction::URem: case Instruction::SRem: case Instruction::FRem: case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: case Instruction::And: case Instruction::Or: case Instruction::Xor: { ValueList LHSVL, RHSVL; for (int i = 0; i < VF; ++i) { RHSVL.push_back(cast<Instruction>(VL[i])->getOperand(0)); LHSVL.push_back(cast<Instruction>(VL[i])->getOperand(1)); } Value *RHS = vectorizeTree(RHSVL, VF); Value *LHS = vectorizeTree(LHSVL, VF); IRBuilder<> Builder(GetLastInstr(VL, VF)); BinaryOperator *BinOp = dyn_cast<BinaryOperator>(VL0); return Builder.CreateBinOp(BinOp->getOpcode(), RHS,LHS); } case Instruction::Load: { LoadInst *LI = dyn_cast<LoadInst>(VL0); unsigned Alignment = LI->getAlignment(); // Check if all of the loads are consecutive. for (unsigned i = 1, e = VF; i < e; ++i) if (!isConsecutiveAccess(VL[i-1], VL[i])) return Scalarize(VL, VecTy); IRBuilder<> Builder(GetLastInstr(VL, VF)); Value *VecPtr = Builder.CreateBitCast(LI->getPointerOperand(), VecTy->getPointerTo()); LI = Builder.CreateLoad(VecPtr); LI->setAlignment(Alignment); return LI; } case Instruction::Store: { StoreInst *SI = dyn_cast<StoreInst>(VL0); unsigned Alignment = SI->getAlignment(); ValueList ValueOp; for (int i = 0; i < VF; ++i) ValueOp.push_back(cast<StoreInst>(VL[i])->getValueOperand()); Value *VecValue = vectorizeTree(ValueOp, VF); IRBuilder<> Builder(GetLastInstr(VL, VF)); Value *VecPtr = Builder.CreateBitCast(SI->getPointerOperand(), VecTy->getPointerTo()); Builder.CreateStore(VecValue, VecPtr)->setAlignment(Alignment); for (int i = 0; i < VF; ++i) cast<Instruction>(VL[i])->eraseFromParent(); return 0; } default: return Scalarize(VL, VecTy); } }