Repository: pytorch
Issue: [JIT] Constant Propagation Shouldn't Run on Values that Escape the Graph
Labels: oncall: jit,days

## 🐛 Bug
When dictionary constants are used to initialized `Dict` type variables, it seems that the constants are shared by all variables that use them, and that all modifications of the logically distinct variables modify the same underlying dictionary.

## To Reproduce
```
from typing import Dict, List, Optional

import torch
import torch.jit as jit
import torch.nn as nn
from torch import Tensor
import torch.nn.functional as F

class TestModule(nn.Module):
    def __init__(self, params: List[Tensor]):
        super().__init__()
        self.param_groups = torch.jit.annotate(List[Dict[str, List[torch.Tensor]]], [])
        self.state = torch.jit.annotate(Dict[torch.Tensor, Dict[str, torch.Tensor]], {})
        self.param_groups = [{"params": params}]
        group = self.param_groups[0]
        for p in group["params"]:
            self.state[p] = {
                "step": torch.tensor(0.0),
            }
        
    @jit.export
    def instance_init(self, params: List[Tensor]):
        self.param_groups = [{"params": params}]
        self.state.clear()
        print(self.state)
        group = self.param_groups[0]
        for p in group["params"]:
            self.state[p] = {
                "step": torch.tensor(0.0),
            }

    @jit.export
    def step_param(self, param: Tensor):
        state = self.state[param]
        step = state["step"]
        step += 1
        current_step = int(step)
        
    @jit.export
    def step(self):
        params = self.param_groups[0]["params"]
        for param in params:
            self.step_param(param)
    @jit.export
    def get_state(self):
        return self.state


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2(x), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

data = torch.randn(10, 1, 1, 28, 28)
target = torch.randint(0, 10, (10, 1))
model1 = Net()
model1_params = list(model1.parameters())
adagrad_module = TestModule([Tensor()])
scripted_optimizer = torch.jit.script(adagrad_module)
scripted_optimizer.instance_init(model1_params)

for i in range(4):
    sample = data[i]
    sample_target = target[i]
    scripted_optimizer.step()
    print ("i:{}".format(i))
    for _,v in scripted_optimizer.get_state().items():
        print("step: {}".format(v["step"]))
```

## Expected behavior
```
i:0
step: 1.0
step: 1.0
step: 1.0
step: 1.0
step: 1.0
step: 1.0
step: 1.0
step: 1.0
i:1
step: 2.0
step: 2.0
step: 2.0
step: 2.0
step: 2.0
step: 2.0
step: 2.0
...
```

## Actual behavior
```
i:0
step: 8.0
step: 8.0
step: 8.0
step: 8.0
step: 8.0
step: 8.0
step: 8.0
step: 8.0
i:1
step: 16.0
step: 16.0
step: 16.0
step: 16.0
step: 16.0
step: 16.0
step: 16.0
...
```

cc @gmagogsfm @eellison