forked from OSchip/llvm-project
				
			
							parent
							
								
									2d958d4db5
								
							
						
					
					
						commit
						e2f482ca0b
					
				| 
						 | 
					@ -129,8 +129,8 @@ struct StrCatOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Extract some information from the instruction
 | 
					    // Extract some information from the instruction
 | 
				
			||||||
    Value *Dst = CI->getOperand(1);
 | 
					    Value *Dst = CI->getArgOperand(0);
 | 
				
			||||||
    Value *Src = CI->getOperand(2);
 | 
					    Value *Src = CI->getArgOperand(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // See if we can get the length of the input string.
 | 
					    // See if we can get the length of the input string.
 | 
				
			||||||
    uint64_t Len = GetStringLength(Src);
 | 
					    uint64_t Len = GetStringLength(Src);
 | 
				
			||||||
| 
						 | 
					@ -181,12 +181,12 @@ struct StrNCatOpt : public StrCatOpt {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Extract some information from the instruction
 | 
					    // Extract some information from the instruction
 | 
				
			||||||
    Value *Dst = CI->getOperand(1);
 | 
					    Value *Dst = CI->getArgOperand(0);
 | 
				
			||||||
    Value *Src = CI->getOperand(2);
 | 
					    Value *Src = CI->getArgOperand(1);
 | 
				
			||||||
    uint64_t Len;
 | 
					    uint64_t Len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // We don't do anything if length is not constant
 | 
					    // We don't do anything if length is not constant
 | 
				
			||||||
    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
 | 
					    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
 | 
				
			||||||
      Len = LengthArg->getZExtValue();
 | 
					      Len = LengthArg->getZExtValue();
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
| 
						 | 
					@ -226,11 +226,11 @@ struct StrChrOpt : public LibCallOptimization {
 | 
				
			||||||
        FT->getParamType(0) != FT->getReturnType())
 | 
					        FT->getParamType(0) != FT->getReturnType())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *SrcStr = CI->getOperand(1);
 | 
					    Value *SrcStr = CI->getArgOperand(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If the second operand is non-constant, see if we can compute the length
 | 
					    // If the second operand is non-constant, see if we can compute the length
 | 
				
			||||||
    // of the input string and turn this into memchr.
 | 
					    // of the input string and turn this into memchr.
 | 
				
			||||||
    ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getOperand(2));
 | 
					    ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
 | 
				
			||||||
    if (CharC == 0) {
 | 
					    if (CharC == 0) {
 | 
				
			||||||
      // These optimizations require TargetData.
 | 
					      // These optimizations require TargetData.
 | 
				
			||||||
      if (!TD) return 0;
 | 
					      if (!TD) return 0;
 | 
				
			||||||
| 
						 | 
					@ -239,7 +239,7 @@ struct StrChrOpt : public LibCallOptimization {
 | 
				
			||||||
      if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
 | 
					      if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return EmitMemChr(SrcStr, CI->getOperand(2), // include nul.
 | 
					      return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul.
 | 
				
			||||||
                        ConstantInt::get(TD->getIntPtrType(*Context), Len),
 | 
					                        ConstantInt::get(TD->getIntPtrType(*Context), Len),
 | 
				
			||||||
                        B, TD);
 | 
					                        B, TD);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -284,7 +284,7 @@ struct StrCmpOpt : public LibCallOptimization {
 | 
				
			||||||
        FT->getParamType(0) != Type::getInt8PtrTy(*Context))
 | 
					        FT->getParamType(0) != Type::getInt8PtrTy(*Context))
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
 | 
					    Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
 | 
				
			||||||
    if (Str1P == Str2P)      // strcmp(x,x)  -> 0
 | 
					    if (Str1P == Str2P)      // strcmp(x,x)  -> 0
 | 
				
			||||||
      return ConstantInt::get(CI->getType(), 0);
 | 
					      return ConstantInt::get(CI->getType(), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -333,13 +333,13 @@ struct StrNCmpOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getParamType(2)->isIntegerTy())
 | 
					        !FT->getParamType(2)->isIntegerTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
 | 
					    Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
 | 
				
			||||||
    if (Str1P == Str2P)      // strncmp(x,x,n)  -> 0
 | 
					    if (Str1P == Str2P)      // strncmp(x,x,n)  -> 0
 | 
				
			||||||
      return ConstantInt::get(CI->getType(), 0);
 | 
					      return ConstantInt::get(CI->getType(), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get the length argument if it is constant.
 | 
					    // Get the length argument if it is constant.
 | 
				
			||||||
    uint64_t Length;
 | 
					    uint64_t Length;
 | 
				
			||||||
    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
 | 
					    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
 | 
				
			||||||
      Length = LengthArg->getZExtValue();
 | 
					      Length = LengthArg->getZExtValue();
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
| 
						 | 
					@ -387,7 +387,7 @@ struct StrCpyOpt : public LibCallOptimization {
 | 
				
			||||||
        FT->getParamType(0) != Type::getInt8PtrTy(*Context))
 | 
					        FT->getParamType(0) != Type::getInt8PtrTy(*Context))
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Dst = CI->getOperand(1), *Src = CI->getOperand(2);
 | 
					    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
 | 
				
			||||||
    if (Dst == Src)      // strcpy(x,x)  -> x
 | 
					    if (Dst == Src)      // strcpy(x,x)  -> x
 | 
				
			||||||
      return Src;
 | 
					      return Src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -403,7 +403,7 @@ struct StrCpyOpt : public LibCallOptimization {
 | 
				
			||||||
    if (OptChkCall)
 | 
					    if (OptChkCall)
 | 
				
			||||||
      EmitMemCpyChk(Dst, Src,
 | 
					      EmitMemCpyChk(Dst, Src,
 | 
				
			||||||
                    ConstantInt::get(TD->getIntPtrType(*Context), Len),
 | 
					                    ConstantInt::get(TD->getIntPtrType(*Context), Len),
 | 
				
			||||||
                    CI->getOperand(3), B, TD);
 | 
					                    CI->getArgOperand(2), B, TD);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      EmitMemCpy(Dst, Src,
 | 
					      EmitMemCpy(Dst, Src,
 | 
				
			||||||
                 ConstantInt::get(TD->getIntPtrType(*Context), Len),
 | 
					                 ConstantInt::get(TD->getIntPtrType(*Context), Len),
 | 
				
			||||||
| 
						 | 
					@ -424,9 +424,9 @@ struct StrNCpyOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getParamType(2)->isIntegerTy())
 | 
					        !FT->getParamType(2)->isIntegerTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Dst = CI->getOperand(1);
 | 
					    Value *Dst = CI->getArgOperand(0);
 | 
				
			||||||
    Value *Src = CI->getOperand(2);
 | 
					    Value *Src = CI->getArgOperand(1);
 | 
				
			||||||
    Value *LenOp = CI->getOperand(3);
 | 
					    Value *LenOp = CI->getArgOperand(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // See if we can get the length of the input string.
 | 
					    // See if we can get the length of the input string.
 | 
				
			||||||
    uint64_t SrcLen = GetStringLength(Src);
 | 
					    uint64_t SrcLen = GetStringLength(Src);
 | 
				
			||||||
| 
						 | 
					@ -474,7 +474,7 @@ struct StrLenOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getReturnType()->isIntegerTy())
 | 
					        !FT->getReturnType()->isIntegerTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Src = CI->getOperand(1);
 | 
					    Value *Src = CI->getArgOperand(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Constant folding: strlen("xyz") -> 3
 | 
					    // Constant folding: strlen("xyz") -> 3
 | 
				
			||||||
    if (uint64_t Len = GetStringLength(Src))
 | 
					    if (uint64_t Len = GetStringLength(Src))
 | 
				
			||||||
| 
						 | 
					@ -499,7 +499,7 @@ struct StrToOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getParamType(1)->isPointerTy())
 | 
					        !FT->getParamType(1)->isPointerTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *EndPtr = CI->getOperand(2);
 | 
					    Value *EndPtr = CI->getArgOperand(1);
 | 
				
			||||||
    if (isa<ConstantPointerNull>(EndPtr)) {
 | 
					    if (isa<ConstantPointerNull>(EndPtr)) {
 | 
				
			||||||
      CI->setOnlyReadsMemory();
 | 
					      CI->setOnlyReadsMemory();
 | 
				
			||||||
      CI->addAttribute(1, Attribute::NoCapture);
 | 
					      CI->addAttribute(1, Attribute::NoCapture);
 | 
				
			||||||
| 
						 | 
					@ -522,8 +522,8 @@ struct StrStrOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fold strstr(x, x) -> x.
 | 
					    // fold strstr(x, x) -> x.
 | 
				
			||||||
    if (CI->getOperand(1) == CI->getOperand(2))
 | 
					    if (CI->getArgOperand(0) == CI->getArgOperand(1))
 | 
				
			||||||
      return B.CreateBitCast(CI->getOperand(1), CI->getType());
 | 
					      return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0
 | 
					    // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0
 | 
				
			||||||
    if (TD && IsOnlyUsedInEqualityComparison(CI, CI->getOperand(1))) {
 | 
					    if (TD && IsOnlyUsedInEqualityComparison(CI, CI->getOperand(1))) {
 | 
				
			||||||
| 
						 | 
					@ -544,12 +544,12 @@ struct StrStrOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // See if either input string is a constant string.
 | 
					    // See if either input string is a constant string.
 | 
				
			||||||
    std::string SearchStr, ToFindStr;
 | 
					    std::string SearchStr, ToFindStr;
 | 
				
			||||||
    bool HasStr1 = GetConstantStringInfo(CI->getOperand(1), SearchStr);
 | 
					    bool HasStr1 = GetConstantStringInfo(CI->getArgOperand(0), SearchStr);
 | 
				
			||||||
    bool HasStr2 = GetConstantStringInfo(CI->getOperand(2), ToFindStr);
 | 
					    bool HasStr2 = GetConstantStringInfo(CI->getArgOperand(1), ToFindStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fold strstr(x, "") -> x.
 | 
					    // fold strstr(x, "") -> x.
 | 
				
			||||||
    if (HasStr2 && ToFindStr.empty())
 | 
					    if (HasStr2 && ToFindStr.empty())
 | 
				
			||||||
      return B.CreateBitCast(CI->getOperand(1), CI->getType());
 | 
					      return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If both strings are known, constant fold it.
 | 
					    // If both strings are known, constant fold it.
 | 
				
			||||||
    if (HasStr1 && HasStr2) {
 | 
					    if (HasStr1 && HasStr2) {
 | 
				
			||||||
| 
						 | 
					@ -559,14 +559,14 @@ struct StrStrOpt : public LibCallOptimization {
 | 
				
			||||||
        return Constant::getNullValue(CI->getType());
 | 
					        return Constant::getNullValue(CI->getType());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // strstr("abcd", "bc") -> gep((char*)"abcd", 1)
 | 
					      // strstr("abcd", "bc") -> gep((char*)"abcd", 1)
 | 
				
			||||||
      Value *Result = CastToCStr(CI->getOperand(1), B);
 | 
					      Value *Result = CastToCStr(CI->getArgOperand(0), B);
 | 
				
			||||||
      Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr");
 | 
					      Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr");
 | 
				
			||||||
      return B.CreateBitCast(Result, CI->getType());
 | 
					      return B.CreateBitCast(Result, CI->getType());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fold strstr(x, "y") -> strchr(x, 'y').
 | 
					    // fold strstr(x, "y") -> strchr(x, 'y').
 | 
				
			||||||
    if (HasStr2 && ToFindStr.size() == 1)
 | 
					    if (HasStr2 && ToFindStr.size() == 1)
 | 
				
			||||||
      return B.CreateBitCast(EmitStrChr(CI->getOperand(1), ToFindStr[0], B, TD),
 | 
					      return B.CreateBitCast(EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TD),
 | 
				
			||||||
                             CI->getType());
 | 
					                             CI->getType());
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -584,13 +584,13 @@ struct MemCmpOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getReturnType()->isIntegerTy(32))
 | 
					        !FT->getReturnType()->isIntegerTy(32))
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
 | 
					    Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (LHS == RHS)  // memcmp(s,s,x) -> 0
 | 
					    if (LHS == RHS)  // memcmp(s,s,x) -> 0
 | 
				
			||||||
      return Constant::getNullValue(CI->getType());
 | 
					      return Constant::getNullValue(CI->getType());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Make sure we have a constant length.
 | 
					    // Make sure we have a constant length.
 | 
				
			||||||
    ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
 | 
					    ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
 | 
				
			||||||
    if (!LenC) return 0;
 | 
					    if (!LenC) return 0;
 | 
				
			||||||
    uint64_t Len = LenC->getZExtValue();
 | 
					    uint64_t Len = LenC->getZExtValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -637,9 +637,9 @@ struct MemCpyOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
 | 
					    // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
 | 
				
			||||||
    EmitMemCpy(CI->getOperand(1), CI->getOperand(2),
 | 
					    EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
 | 
				
			||||||
               CI->getOperand(3), 1, false, B, TD);
 | 
					               CI->getArgOperand(2), 1, false, B, TD);
 | 
				
			||||||
    return CI->getOperand(1);
 | 
					    return CI->getArgOperand(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -659,9 +659,9 @@ struct MemMoveOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
 | 
					    // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
 | 
				
			||||||
    EmitMemMove(CI->getOperand(1), CI->getOperand(2),
 | 
					    EmitMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
 | 
				
			||||||
                CI->getOperand(3), 1, false, B, TD);
 | 
					                CI->getArgOperand(2), 1, false, B, TD);
 | 
				
			||||||
    return CI->getOperand(1);
 | 
					    return CI->getArgOperand(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -681,10 +681,10 @@ struct MemSetOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // memset(p, v, n) -> llvm.memset(p, v, n, 1)
 | 
					    // memset(p, v, n) -> llvm.memset(p, v, n, 1)
 | 
				
			||||||
    Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context),
 | 
					    Value *Val = B.CreateIntCast(CI->getArgOperand(1), Type::getInt8Ty(*Context),
 | 
				
			||||||
				 false);
 | 
									 false);
 | 
				
			||||||
    EmitMemSet(CI->getOperand(1), Val,  CI->getOperand(3), false, B, TD);
 | 
					    EmitMemSet(CI->getArgOperand(0), Val,  CI->getArgOperand(2), false, B, TD);
 | 
				
			||||||
    return CI->getOperand(1);
 | 
					    return CI->getArgOperand(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -705,7 +705,7 @@ struct PowOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getParamType(0)->isFloatingPointTy())
 | 
					        !FT->getParamType(0)->isFloatingPointTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2);
 | 
					    Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1);
 | 
				
			||||||
    if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
 | 
					    if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
 | 
				
			||||||
      if (Op1C->isExactlyValue(1.0))  // pow(1.0, x) -> 1.0
 | 
					      if (Op1C->isExactlyValue(1.0))  // pow(1.0, x) -> 1.0
 | 
				
			||||||
        return Op1C;
 | 
					        return Op1C;
 | 
				
			||||||
| 
						 | 
					@ -759,7 +759,7 @@ struct Exp2Opt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getParamType(0)->isFloatingPointTy())
 | 
					        !FT->getParamType(0)->isFloatingPointTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Op = CI->getOperand(1);
 | 
					    Value *Op = CI->getArgOperand(0);
 | 
				
			||||||
    // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x))  if sizeof(x) <= 32
 | 
					    // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x))  if sizeof(x) <= 32
 | 
				
			||||||
    // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x))  if sizeof(x) < 32
 | 
					    // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x))  if sizeof(x) < 32
 | 
				
			||||||
    Value *LdExpArg = 0;
 | 
					    Value *LdExpArg = 0;
 | 
				
			||||||
| 
						 | 
					@ -811,7 +811,7 @@ struct UnaryDoubleFPOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If this is something like 'floor((double)floatval)', convert to floorf.
 | 
					    // If this is something like 'floor((double)floatval)', convert to floorf.
 | 
				
			||||||
    FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getOperand(1));
 | 
					    FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0));
 | 
				
			||||||
    if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy())
 | 
					    if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -840,7 +840,7 @@ struct FFSOpt : public LibCallOptimization {
 | 
				
			||||||
        !FT->getParamType(0)->isIntegerTy())
 | 
					        !FT->getParamType(0)->isIntegerTy())
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Value *Op = CI->getOperand(1);
 | 
					    Value *Op = CI->getArgOperand(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Constant fold.
 | 
					    // Constant fold.
 | 
				
			||||||
    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
 | 
					    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
 | 
				
			||||||
| 
						 | 
					@ -876,7 +876,7 @@ struct IsDigitOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // isdigit(c) -> (c-'0') <u 10
 | 
					    // isdigit(c) -> (c-'0') <u 10
 | 
				
			||||||
    Value *Op = CI->getOperand(1);
 | 
					    Value *Op = CI->getArgOperand(0);
 | 
				
			||||||
    Op = B.CreateSub(Op, ConstantInt::get(Type::getInt32Ty(*Context), '0'),
 | 
					    Op = B.CreateSub(Op, ConstantInt::get(Type::getInt32Ty(*Context), '0'),
 | 
				
			||||||
                     "isdigittmp");
 | 
					                     "isdigittmp");
 | 
				
			||||||
    Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 10),
 | 
					    Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 10),
 | 
				
			||||||
| 
						 | 
					@ -897,7 +897,7 @@ struct IsAsciiOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // isascii(c) -> c <u 128
 | 
					    // isascii(c) -> c <u 128
 | 
				
			||||||
    Value *Op = CI->getOperand(1);
 | 
					    Value *Op = CI->getArgOperand(0);
 | 
				
			||||||
    Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 128),
 | 
					    Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 128),
 | 
				
			||||||
                         "isascii");
 | 
					                         "isascii");
 | 
				
			||||||
    return B.CreateZExt(Op, CI->getType());
 | 
					    return B.CreateZExt(Op, CI->getType());
 | 
				
			||||||
| 
						 | 
					@ -916,7 +916,7 @@ struct AbsOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // abs(x) -> x >s -1 ? x : -x
 | 
					    // abs(x) -> x >s -1 ? x : -x
 | 
				
			||||||
    Value *Op = CI->getOperand(1);
 | 
					    Value *Op = CI->getArgOperand(0);
 | 
				
			||||||
    Value *Pos = B.CreateICmpSGT(Op,
 | 
					    Value *Pos = B.CreateICmpSGT(Op,
 | 
				
			||||||
                             Constant::getAllOnesValue(Op->getType()),
 | 
					                             Constant::getAllOnesValue(Op->getType()),
 | 
				
			||||||
                                 "ispos");
 | 
					                                 "ispos");
 | 
				
			||||||
| 
						 | 
					@ -938,7 +938,7 @@ struct ToAsciiOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // isascii(c) -> c & 0x7f
 | 
					    // isascii(c) -> c & 0x7f
 | 
				
			||||||
    return B.CreateAnd(CI->getOperand(1),
 | 
					    return B.CreateAnd(CI->getArgOperand(0),
 | 
				
			||||||
                       ConstantInt::get(CI->getType(),0x7F));
 | 
					                       ConstantInt::get(CI->getType(),0x7F));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -961,7 +961,7 @@ struct PrintFOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Check for a fixed format string.
 | 
					    // Check for a fixed format string.
 | 
				
			||||||
    std::string FormatStr;
 | 
					    std::string FormatStr;
 | 
				
			||||||
    if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
 | 
					    if (!GetConstantStringInfo(CI->getArgOperand(0), FormatStr))
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Empty format string -> noop.
 | 
					    // Empty format string -> noop.
 | 
				
			||||||
| 
						 | 
					@ -993,10 +993,10 @@ struct PrintFOpt : public LibCallOptimization {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Optimize specific format strings.
 | 
					    // Optimize specific format strings.
 | 
				
			||||||
    // printf("%c", chr) --> putchar(*(i8*)dst)
 | 
					    // printf("%c", chr) --> putchar(chr)
 | 
				
			||||||
    if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
 | 
					    if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
 | 
				
			||||||
        CI->getOperand(2)->getType()->isIntegerTy()) {
 | 
					        CI->getArgOperand(1)->getType()->isIntegerTy()) {
 | 
				
			||||||
      Value *Res = EmitPutChar(CI->getOperand(2), B, TD);
 | 
					      Value *Res = EmitPutChar(CI->getArgOperand(1), B, TD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (CI->use_empty()) return CI;
 | 
					      if (CI->use_empty()) return CI;
 | 
				
			||||||
      return B.CreateIntCast(Res, CI->getType(), true);
 | 
					      return B.CreateIntCast(Res, CI->getType(), true);
 | 
				
			||||||
| 
						 | 
					@ -1004,9 +1004,9 @@ struct PrintFOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // printf("%s\n", str) --> puts(str)
 | 
					    // printf("%s\n", str) --> puts(str)
 | 
				
			||||||
    if (FormatStr == "%s\n" && CI->getNumOperands() > 2 &&
 | 
					    if (FormatStr == "%s\n" && CI->getNumOperands() > 2 &&
 | 
				
			||||||
        CI->getOperand(2)->getType()->isPointerTy() &&
 | 
					        CI->getArgOperand(1)->getType()->isPointerTy() &&
 | 
				
			||||||
        CI->use_empty()) {
 | 
					        CI->use_empty()) {
 | 
				
			||||||
      EmitPutS(CI->getOperand(2), B, TD);
 | 
					      EmitPutS(CI->getArgOperand(1), B, TD);
 | 
				
			||||||
      return CI;
 | 
					      return CI;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
| 
						 | 
					@ -1027,7 +1027,7 @@ struct SPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Check for a fixed format string.
 | 
					    // Check for a fixed format string.
 | 
				
			||||||
    std::string FormatStr;
 | 
					    std::string FormatStr;
 | 
				
			||||||
    if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
 | 
					    if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr))
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If we just have a format string (nothing else crazy) transform it.
 | 
					    // If we just have a format string (nothing else crazy) transform it.
 | 
				
			||||||
| 
						 | 
					@ -1042,7 +1042,7 @@ struct SPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
      if (!TD) return 0;
 | 
					      if (!TD) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
 | 
					      // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
 | 
				
			||||||
      EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte.
 | 
					      EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), // Copy the nul byte.
 | 
				
			||||||
                 ConstantInt::get(TD->getIntPtrType(*Context),
 | 
					                 ConstantInt::get(TD->getIntPtrType(*Context),
 | 
				
			||||||
                 FormatStr.size()+1), 1, false, B, TD);
 | 
					                 FormatStr.size()+1), 1, false, B, TD);
 | 
				
			||||||
      return ConstantInt::get(CI->getType(), FormatStr.size());
 | 
					      return ConstantInt::get(CI->getType(), FormatStr.size());
 | 
				
			||||||
| 
						 | 
					@ -1056,10 +1056,10 @@ struct SPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
    // Decode the second character of the format string.
 | 
					    // Decode the second character of the format string.
 | 
				
			||||||
    if (FormatStr[1] == 'c') {
 | 
					    if (FormatStr[1] == 'c') {
 | 
				
			||||||
      // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
 | 
					      // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
 | 
				
			||||||
      if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0;
 | 
					      if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
 | 
				
			||||||
      Value *V = B.CreateTrunc(CI->getOperand(3),
 | 
					      Value *V = B.CreateTrunc(CI->getArgOperand(2),
 | 
				
			||||||
                               Type::getInt8Ty(*Context), "char");
 | 
					                               Type::getInt8Ty(*Context), "char");
 | 
				
			||||||
      Value *Ptr = CastToCStr(CI->getOperand(1), B);
 | 
					      Value *Ptr = CastToCStr(CI->getArgOperand(0), B);
 | 
				
			||||||
      B.CreateStore(V, Ptr);
 | 
					      B.CreateStore(V, Ptr);
 | 
				
			||||||
      Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1),
 | 
					      Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1),
 | 
				
			||||||
                        "nul");
 | 
					                        "nul");
 | 
				
			||||||
| 
						 | 
					@ -1073,13 +1073,13 @@ struct SPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
      if (!TD) return 0;
 | 
					      if (!TD) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
 | 
					      // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
 | 
				
			||||||
      if (!CI->getOperand(3)->getType()->isPointerTy()) return 0;
 | 
					      if (!CI->getArgOperand(2)->getType()->isPointerTy()) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Value *Len = EmitStrLen(CI->getOperand(3), B, TD);
 | 
					      Value *Len = EmitStrLen(CI->getArgOperand(2), B, TD);
 | 
				
			||||||
      Value *IncLen = B.CreateAdd(Len,
 | 
					      Value *IncLen = B.CreateAdd(Len,
 | 
				
			||||||
                                  ConstantInt::get(Len->getType(), 1),
 | 
					                                  ConstantInt::get(Len->getType(), 1),
 | 
				
			||||||
                                  "leninc");
 | 
					                                  "leninc");
 | 
				
			||||||
      EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, false, B, TD);
 | 
					      EmitMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1, false, B, TD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // The sprintf result is the unincremented number of bytes in the string.
 | 
					      // The sprintf result is the unincremented number of bytes in the string.
 | 
				
			||||||
      return B.CreateIntCast(Len, CI->getType(), false);
 | 
					      return B.CreateIntCast(Len, CI->getType(), false);
 | 
				
			||||||
| 
						 | 
					@ -1103,8 +1103,8 @@ struct FWriteOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get the element size and count.
 | 
					    // Get the element size and count.
 | 
				
			||||||
    ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getOperand(2));
 | 
					    ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
 | 
				
			||||||
    ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getOperand(3));
 | 
					    ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
 | 
				
			||||||
    if (!SizeC || !CountC) return 0;
 | 
					    if (!SizeC || !CountC) return 0;
 | 
				
			||||||
    uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
 | 
					    uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1114,8 +1114,8 @@ struct FWriteOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If this is writing one byte, turn it into fputc.
 | 
					    // If this is writing one byte, turn it into fputc.
 | 
				
			||||||
    if (Bytes == 1) {  // fwrite(S,1,1,F) -> fputc(S[0],F)
 | 
					    if (Bytes == 1) {  // fwrite(S,1,1,F) -> fputc(S[0],F)
 | 
				
			||||||
      Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char");
 | 
					      Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char");
 | 
				
			||||||
      EmitFPutC(Char, CI->getOperand(4), B, TD);
 | 
					      EmitFPutC(Char, CI->getArgOperand(3), B, TD);
 | 
				
			||||||
      return ConstantInt::get(CI->getType(), 1);
 | 
					      return ConstantInt::get(CI->getType(), 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1139,11 +1139,11 @@ struct FPutsOpt : public LibCallOptimization {
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fputs(s,F) --> fwrite(s,1,strlen(s),F)
 | 
					    // fputs(s,F) --> fwrite(s,1,strlen(s),F)
 | 
				
			||||||
    uint64_t Len = GetStringLength(CI->getOperand(1));
 | 
					    uint64_t Len = GetStringLength(CI->getArgOperand(0));
 | 
				
			||||||
    if (!Len) return 0;
 | 
					    if (!Len) return 0;
 | 
				
			||||||
    EmitFWrite(CI->getOperand(1),
 | 
					    EmitFWrite(CI->getArgOperand(0),
 | 
				
			||||||
               ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
 | 
					               ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
 | 
				
			||||||
               CI->getOperand(2), B, TD);
 | 
					               CI->getArgOperand(1), B, TD);
 | 
				
			||||||
    return CI;  // Known to have no uses (see above).
 | 
					    return CI;  // Known to have no uses (see above).
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1162,7 +1162,7 @@ struct FPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // All the optimizations depend on the format string.
 | 
					    // All the optimizations depend on the format string.
 | 
				
			||||||
    std::string FormatStr;
 | 
					    std::string FormatStr;
 | 
				
			||||||
    if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
 | 
					    if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr))
 | 
				
			||||||
      return 0;
 | 
					      return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
 | 
					    // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
 | 
				
			||||||
| 
						 | 
					@ -1174,10 +1174,10 @@ struct FPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
      // These optimizations require TargetData.
 | 
					      // These optimizations require TargetData.
 | 
				
			||||||
      if (!TD) return 0;
 | 
					      if (!TD) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      EmitFWrite(CI->getOperand(2),
 | 
					      EmitFWrite(CI->getArgOperand(1),
 | 
				
			||||||
                 ConstantInt::get(TD->getIntPtrType(*Context),
 | 
					                 ConstantInt::get(TD->getIntPtrType(*Context),
 | 
				
			||||||
                                  FormatStr.size()),
 | 
					                                  FormatStr.size()),
 | 
				
			||||||
                 CI->getOperand(1), B, TD);
 | 
					                 CI->getArgOperand(0), B, TD);
 | 
				
			||||||
      return ConstantInt::get(CI->getType(), FormatStr.size());
 | 
					      return ConstantInt::get(CI->getType(), FormatStr.size());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1188,17 +1188,17 @@ struct FPrintFOpt : public LibCallOptimization {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Decode the second character of the format string.
 | 
					    // Decode the second character of the format string.
 | 
				
			||||||
    if (FormatStr[1] == 'c') {
 | 
					    if (FormatStr[1] == 'c') {
 | 
				
			||||||
      // fprintf(F, "%c", chr) --> *(i8*)dst = chr
 | 
					      // fprintf(F, "%c", chr) --> fputc(chr, F)
 | 
				
			||||||
      if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0;
 | 
					      if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
 | 
				
			||||||
      EmitFPutC(CI->getOperand(3), CI->getOperand(1), B, TD);
 | 
					      EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, TD);
 | 
				
			||||||
      return ConstantInt::get(CI->getType(), 1);
 | 
					      return ConstantInt::get(CI->getType(), 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (FormatStr[1] == 's') {
 | 
					    if (FormatStr[1] == 's') {
 | 
				
			||||||
      // fprintf(F, "%s", str) -> fputs(str, F)
 | 
					      // fprintf(F, "%s", str) --> fputs(str, F)
 | 
				
			||||||
      if (!CI->getOperand(3)->getType()->isPointerTy() || !CI->use_empty())
 | 
					      if (!CI->getArgOperand(2)->getType()->isPointerTy() || !CI->use_empty())
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
      EmitFPutS(CI->getOperand(3), CI->getOperand(1), B, TD);
 | 
					      EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD);
 | 
				
			||||||
      return CI;
 | 
					      return CI;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue