Example #1
0
bool GambasPass::runOnFunction(Function &F){
	IRBuilder<> Builder(F.getContext());
	
	bool changed = false;
	for(Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
		for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ){
			ICmpInst* ICI = dyn_cast<ICmpInst>(I);
			CallInst* CI = dyn_cast<CallInst>(I++);
			
			if (ICI && ICI->hasMetadata() && ICI->getMetadata("unref_slt") && dyn_cast<LoadInst>(ICI->getOperand(0))){
				ICI->replaceAllUsesWith(ConstantInt::get(ICI->getType(), false));
				ICI->eraseFromParent();
				changed = true;
				continue;
			}
			
			if (!CI)
				continue;
			
			Function* callee = CI->getCalledFunction();
			if (callee == NULL || !callee->isDeclaration())
				continue;
			
			StringRef name = callee->getName();
			if (name == "JR_release_variant" || name == "JR_borrow_variant"){
				ConstantInt* vtype_int = dyn_cast<ConstantInt>(CI->getArgOperand(0));
				if (!vtype_int)
					continue;
				
				uint64_t vtype = vtype_int->getZExtValue();
				if (TYPE_is_string(vtype) || TYPE_is_object(vtype))
					continue;
				
				CI->eraseFromParent();
				changed = true;
			} else if (name == FUNCTION_NAME(__finite)){
				ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0));
				if (!op)
					continue;
				
				int val = __finite(op->getValueAPF().convertToDouble());
				Constant* res = ConstantInt::get(CI->getType(), val);
				CI->replaceAllUsesWith(res);
				CI->eraseFromParent();
				changed = true;
			} else if (name == FUNCTION_NAME(__isnan)){
				ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0));
				if (!op)
					continue;
				
				int val = __isnan(op->getValueAPF().convertToDouble());
				Constant* res = ConstantInt::get(CI->getType(), val);
				CI->replaceAllUsesWith(res);
				CI->eraseFromParent();
				changed = true;
			} else if (name == FUNCTION_NAME(__isinf)){
				ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0));
				if (!op)
					continue;
				
				int val = __isinf(op->getValueAPF().convertToDouble());
				Constant* res = ConstantInt::get(CI->getType(), val);
				CI->replaceAllUsesWith(res);
				CI->eraseFromParent();
				changed = true;
			}
		}
	}
	return changed;
}