llvm.org GIT mirror llvm / 1ca39a4
Get constant cloning out of CloneValue so it can be used when creating globals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260848 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury Sechet 4 years ago
1 changed file(s) with 48 addition(s) and 41 deletion(s). Raw diff Collapse all Expand all
5858 LLVMContextRef Ctx;
5959
6060 TypeCloner(LLVMModuleRef M): M(M), Ctx(LLVMGetModuleContext(M)) {}
61
62 LLVMTypeRef Clone(LLVMValueRef Src) {
63 return Clone(LLVMTypeOf(Src));
64 }
6165
6266 LLVMTypeRef Clone(LLVMTypeRef Src) {
6367 LLVMTypeKind Kind = LLVMGetTypeKind(Src);
225229 return VMap;
226230 }
227231
232 LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
233 if (!LLVMIsAConstant(Cst))
234 report_fatal_error("Expected a constant");
235
236 // Maybe it is a symbol
237 if (LLVMIsAGlobalValue(Cst)) {
238 const char *Name = LLVMGetValueName(Cst);
239
240 // Try function
241 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
242 if (Dst != nullptr)
243 return Dst;
244
245 // Try global variable
246 Dst = LLVMGetNamedGlobal(M, Name);
247 if (Dst != nullptr)
248 return Dst;
249
250 fprintf(stderr, "Could not find @%s\n", Name);
251 exit(-1);
252 }
253
254 // Try literal
255 if (LLVMIsAConstantInt(Cst))
256 return LLVMConstInt(TypeCloner(M).Clone(Cst),
257 LLVMConstIntGetZExtValue(Cst), false);
258
259 // Try undef
260 if (LLVMIsUndef(Cst))
261 return LLVMGetUndef(TypeCloner(M).Clone(Cst));
262
263 // This kind of constant is not supported.
264 report_fatal_error("Unsupported contant type");
265 }
266
228267 struct FunCloner {
229268 LLVMValueRef Fun;
230269 LLVMModuleRef M;
240279 }
241280
242281 LLVMTypeRef CloneType(LLVMValueRef Src) {
243 return CloneType(LLVMTypeOf(Src));
282 return TypeCloner(M).Clone(Src);
244283 }
245284
246285 // Try to clone everything in the llvm::Value hierarchy.
247286 LLVMValueRef CloneValue(LLVMValueRef Src) {
248 const char *Name = LLVMGetValueName(Src);
249
250287 // First, the value may be constant.
251 if (LLVMIsAConstant(Src)) {
252 // Maybe it is a symbol
253 if (LLVMIsAGlobalValue(Src)) {
254 // Try function
255 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
256 if (Dst != nullptr)
257 return Dst;
258
259 // Try global variable
260 Dst = LLVMGetNamedGlobal(M, Name);
261 if (Dst != nullptr)
262 return Dst;
263
264 fprintf(stderr, "Could not find @%s\n", Name);
265 exit(-1);
266 }
267
268 // Try literal
269 if (LLVMIsAConstantInt(Src)) {
270 LLVMTypeRef Ty = CloneType(Src);
271 return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
272 }
273
274 // Try undef
275 if (LLVMIsUndef(Src))
276 return LLVMGetUndef(CloneType(Src));
277
278 // This kind of constant is not supported.
279 report_fatal_error("Unsupported contant type");
280 }
288 if (LLVMIsAConstant(Src))
289 return clone_constant(Src, M);
281290
282291 // Function argument should always be in the map already.
283292 auto i = VMap.find(Src);
615624 if (Fun != nullptr)
616625 return Fun;
617626
618 LLVMTypeRef DstTy = TypeCloner(M).Clone(LLVMTypeOf(Src));
619 LLVMTypeRef FunTy = LLVMGetElementType(DstTy);
620
627 LLVMTypeRef FunTy = LLVMGetElementType(TypeCloner(M).Clone(Src));
621628 Fun = LLVMAddFunction(M, Name, FunTy);
622629 FunCloner FC(Src, Fun);
623630 FC.CloneBBs(Src);
659666 LLVMModuleRef Src = llvm_load_module(false, true);
660667
661668 LLVMContextRef Ctx = LLVMContextCreate();
662 LLVMModuleRef Dst = LLVMModuleCreateWithNameInContext("", Ctx);
663
664 clone_functions(Src, Dst);
665 char *Str = LLVMPrintModuleToString(Dst);
669 LLVMModuleRef M = LLVMModuleCreateWithNameInContext("", Ctx);
670
671 clone_functions(Src, M);
672 char *Str = LLVMPrintModuleToString(M);
666673 fputs(Str, stdout);
667674
668675 LLVMDisposeMessage(Str);
669 LLVMDisposeModule(Dst);
676 LLVMDisposeModule(M);
670677 LLVMContextDispose(Ctx);
671678
672679 return 0;